// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
**  File:    ActivationServices.cs 
**
**  Author(s): 
**
**  Purpose:
**
** 
===========================================================*/
namespace System.Runtime.Remoting.Activation { 
 
    using System;
    using System.Security; 
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Contexts; 
    using System.Runtime.Remoting.Proxies;
    using System.Runtime.Remoting.Messaging; 
    using System.Runtime.Remoting.Metadata; 
    using System.Collections;
    using System.Reflection; 
    using System.IO;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Runtime.CompilerServices;
    using System.Diagnostics.Contracts; 
 
    // Implements various activation services
    internal static class ActivationServices 
    {

        private static IActivator activator = null;
 
        private static Hashtable _proxyTable = new Hashtable();
        private static Type proxyAttributeType = typeof(System.Runtime.Remoting.Proxies.ProxyAttribute); 
        [System.Security.SecurityCritical /*auto-generated*/] 
        private static ProxyAttribute _proxyAttribute = new ProxyAttribute();
        [ThreadStaticAttribute()] 
        internal static ActivationAttributeStack _attributeStack;

        internal const String ActivationServiceURI = "RemoteActivationService.rem";
 
        internal const String RemoteActivateKey = "Remote";
        internal const String PermissionKey = "Permission"; 
        internal const String ConnectKey = "Connect"; 

        [System.Security.SecuritySafeCritical] // static constructors should be safe to call 
        static ActivationServices()
        { }

        // < 

 
 

 
        //1 private static LocalActivator  localActivator = null;

        // ActivationListener is the object that listens to incoming
        // activation requests. It delegates the incoming request to 
        // the local activator.
        //2 private static ActivationListener ActivationListener = null; 
 
        //3 private static Object staticSyncObject = new Object();
        //4 private static bool bInitializing = false; 

        // This gets called upon the first attempt to activate
        // anything that is ContextBound or MarshalByRef
        [System.Security.SecurityCritical]  // auto-generated 
        private static void Startup()
        { 
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 

            // wait on the lock if a)activation has not been initialized yet 
            // or b) activation is being initialized by another thread!
            if ((!remData.ActivationInitialized)
               || remData.InitializingActivation)
            { 
                Object configLock = remData.ConfigLock;
                bool fLocked = false; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try
                { 
                    Monitor.Enter(configLock, ref fLocked);
                    remData.InitializingActivation = true;
                    // Ensure that some other thread did not complete
                    // the work while we were waiting on the lock. 
                    if (!remData.ActivationInitialized)
                    { 
                        // Startup the activation service 
                        BCLDebug.Trace("REMOTE","Starting up activation service ",Thread.CurrentContext);
 
                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                        // NOTE: This should be the first step in Startup!
                        // Otherwise activation will recurse, when we try
                        // to create the ActivationListener (which is MarshalByRef) 
                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                        remData.LocalActivator = new LocalActivator(); 
 
                        // Add the Lifetime service property to the appdomain.
                        // For now we are assuming that this is the only property 
                        // If there are more properties, then an existing array
                        // will need to be expanded to add this property

                        // This is activated in RemotingServices.DomainSpecificRemotingData() 
                        // IContextProperty[] contextProperties = new IContextProperty[1];
                        // contextProperties[0] = new System.Runtime.Remoting.LeaseLifeTimeServiceProperty(); 
                        // Thread.GetDomain().RemotingData.AppDomainContextProperties = contextProperties; 

                        remData.ActivationListener = new ActivationListener(); 
                        remData.ActivationInitialized = true;

                    }
 
                    remData.InitializingActivation = false;
                } //lock (remData) 
                finally 
                {
                    if (fLocked) 
                    {
                        Monitor.Exit(configLock);
                    }
                } 
            }
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        private static void InitActivationServices() 
        {
            // If activation services has not been loaded do it now and create
            // the instace that will service the activation requests.
            if (null == activator) 
            {
                activator = GetActivator(); 
                if (null == activator) 
                {
                    Message.DebugOut("Fatal Error... Could not create activator\n"); 
                    throw new RemotingException(
                        String.Format(
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_BadInternalState_ActivationFailure"))); 
                }
            } 
        } 

        // Determine whether the current context is ok for the activation. 
        [System.Security.SecurityCritical]  // auto-generated
        private static MarshalByRefObject IsCurrentContextOK(
            RuntimeType serverType, Object[] props, bool bNewObj)
        { 
            Contract.Assert(!serverType.IsInterface,"!serverType.IsInterface");
 
            MarshalByRefObject retObj = null; 

            // Initialize activation services if needed. 
            //   (we temporary null out the activation attributes in case
            //    InitActivationServices creates an MBR).
            InitActivationServices();
 
            // Obtain the method info which will create an instance
            // of type RealProxy 
            ProxyAttribute pa = GetProxyAttribute(serverType); 
            Contract.Assert(null != pa, "null != pa");
 
            if (Object.ReferenceEquals(pa, DefaultProxyAttribute))
                retObj = pa.CreateInstanceInternal(serverType);
            else
            { 
                retObj = pa.CreateInstance(serverType);
                // We called a custom proxy attribute .. make sure it is 
                // returning a server of the correct type. 
                if (retObj != null)
                { 
                    // If a transparent proxy is returned we are fine.
                    // If not then the object's type MUST be compatible
                    // with the type we were requested to activate!
                    if (!RemotingServices.IsTransparentProxy(retObj) 
                        && !serverType.IsAssignableFrom(retObj.GetType()))
                    { 
                        throw new RemotingException( 
                            String.Format(
                                CultureInfo.CurrentCulture, Environment.GetResourceString( 
                                    "Remoting_Activation_BadObject"),
                            serverType));
                    }
                } 
            }
            Contract.Assert(null != retObj, "null != retObj"); 
            return retObj; 
        }
 
#if FEATURE_COMINTEROP
        [System.Security.SecurityCritical]  // auto-generated
        private static MarshalByRefObject CreateObjectForCom(
            RuntimeType serverType, Object[] props, bool bNewObj) 
        {
            Contract.Assert(!serverType.IsInterface,"!serverType.IsInterface"); 
 
            MarshalByRefObject retObj = null;
 
            if (PeekActivationAttributes(serverType) != null)
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_ActivForCom" ));

            // Initialize activation services if needed 
            InitActivationServices();
 
            // Obtain the method info which will create an instance 
            // of type RealProxy
            ProxyAttribute pa = GetProxyAttribute(serverType); 
            Contract.Assert(null != pa, "null != pa");

            if(pa is ICustomFactory)
            { 
                retObj = ((ICustomFactory)pa).CreateInstance(serverType);
            } 
            else 
            {
                retObj = (MarshalByRefObject)Activator.CreateInstance(serverType, true); 
            }

            Contract.Assert(null != retObj, "null != retObj");
            return retObj; 
        }
#endif // FEATURE_COMINTEROP 
 
        // For types with no proxy attribute, we take the default route of
        // querying attributes if the current context is suitable for 
        // activation.
        [System.Security.SecurityCritical]  // auto-generated
        private static bool IsCurrentContextOK(RuntimeType serverType, Object[] props,
                                               ref ConstructorCallMessage ctorCallMsg) 
        {
             //Get callSite attributes 
            Object[] callSiteAttr = PeekActivationAttributes(serverType); 

            // Clear from the attribute stack 
            if (callSiteAttr != null)
            {
                PopActivationAttributes(serverType);
            } 

            Object[] womAttr = new Object[1]; 
            womAttr[0] = GetGlobalAttribute(); 

            // Get the type context attributes 
            Object[] typeAttr = GetContextAttributesForType(serverType);

            // Get the client context (current context)
            Context cliCtx = Thread.CurrentContext; 

            // Create a ctorCallMsg with the reqd info 
            ctorCallMsg = 
                new ConstructorCallMessage(
                    callSiteAttr, 
                    womAttr,
                    typeAttr,
                    serverType);
 
            // This is the activator that handles activation in *all* cases
            // Based on whether what the activation attributes do.... other 
            // activators may get chained ahead of this one and may take 
            // over the activation process... (possibly) delegating to this
            // only in the last stage. 
            // Note: currently, this does not get used in the same context (MBR)
            // scenarios ... because of the 2-step activation model of JIT.
            ctorCallMsg.Activator = new ConstructionLevelActivator();
 

            // Ask all attributes if they are happy with the current context 
            // NOTE: if someone says no, we do not ask the rest of the attributes 
            // This is why, womAttr (which is the global activation service
            // attribute) *must* be the first one we query. 
            bool bCtxOK = QueryAttributesIfContextOK(cliCtx,
                                                     ctorCallMsg,
                                                     womAttr);
            if (bCtxOK == true) 
            {
                bCtxOK = QueryAttributesIfContextOK(cliCtx, 
                                                    ctorCallMsg, 
                                                    callSiteAttr);
                if (bCtxOK == true) 
                {
                    bCtxOK = QueryAttributesIfContextOK(cliCtx,
                                                        ctorCallMsg,
                                                        typeAttr); 
                }
            } 
 
            return bCtxOK;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        private static void CheckForInfrastructurePermission(RuntimeAssembly asm)
        { 
            // Make a security check to ensure that the context attribute
            // is from a trusted assembly! 
            if (asm != RemotingServices.s_MscorlibAssembly) 
            {
                CodeAccessSecurityEngine.CheckAssembly(asm, RemotingServices.s_RemotingInfrastructurePermission); 
            }
        }

        [System.Security.SecurityCritical]  // auto-generated 
        private static bool QueryAttributesIfContextOK(
            Context ctx, IConstructionCallMessage ctorMsg, Object[] attributes) 
        { 
            bool bCtxOK = true;
            if (attributes != null) 
            {
                for (int i=0; i<attributes.Length; i++)
                {
                    // All the attributes, including callsite attributes should 
                    // expose IContextAttribute. If not, then we throw an
                    // exception. 
                    IContextAttribute attr = attributes[i] as IContextAttribute; 
                    if(null != attr)
                    { 
                        RuntimeAssembly asm = (RuntimeAssembly)attr.GetType().Assembly;
                        // Make a security check to ensure that the context attribute
                        // is from a trusted assembly!
                        CheckForInfrastructurePermission(asm); 

                        bCtxOK = attr.IsContextOK(ctx, ctorMsg); 
                        if (bCtxOK == false) 
                        {
                            break; 
                        }
                    }
                    else
                    { 
                        throw new RemotingException(
                                Environment.GetResourceString( 
                                    "Remoting_Activation_BadAttribute")); 
                    }
                } 
            }
            return bCtxOK;
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void GetPropertiesFromAttributes( 
            IConstructionCallMessage ctorMsg, Object[] attributes) 
        {
            if (attributes != null) 
            {
                for (int i=0; i<attributes.Length; i++)
                {
                    // All the attributes, including callsite attributes should 
                    // expose IContextAttribute. If not, then we throw an
                    // exception. 
                    IContextAttribute attr = attributes[i] as IContextAttribute; 
                    if(null != attr)
                    { 
                        RuntimeAssembly asm = (RuntimeAssembly)attr.GetType().Assembly;
                        // Make a security check to ensure that the context attribute
                        // is from a trusted assembly!
                        CheckForInfrastructurePermission(asm); 

                        // We ask each attribute to contribute its properties. 
                        // The attributes can examine the current list of properties 
                        // from the ctorCallMsg and decide which properties to add.
 
                        // They can also tweak the Activator chain during this process
                        attr.GetPropertiesForNewContext(ctorMsg);
                    }
                    else 
                    {
                        throw new RemotingException( 
                            Environment.GetResourceString( 
                                "Remoting_Activation_BadAttribute"));
                    } 
                }
            }
        }
 
        // Return the default implementation of the proxy attribute
        internal static ProxyAttribute DefaultProxyAttribute 
        { 
            [System.Security.SecurityCritical]  // auto-generated
            get { return _proxyAttribute; } 
        }

        // Iterate over the custom attributes of the class and see if it
        // defines a ProxyAttribute. If one is not defined then return 
        // the default proxy attribute defined by us.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static ProxyAttribute GetProxyAttribute(Type serverType) 
        {
 
            Contract.Assert(
                serverType.IsMarshalByRef,
                "type should be at least marshal-by-ref");
 
            if (!serverType.HasProxyAttribute)
                return DefaultProxyAttribute; 
 
            // Type has a non-default proxy attribute ... see if we have
            // it cached? 
            ProxyAttribute pa = _proxyTable[serverType] as ProxyAttribute;

            if (pa == null)
            { 
                Object[] ca = Attribute.GetCustomAttributes(
                                            serverType, 
                                            proxyAttributeType, 
                                            true);
                if((null != ca) && (0 != ca.Length)) 
                {
                    if (!serverType.IsContextful)
                    {
                        throw new RemotingException( 
                                    Environment.GetResourceString(
                                    "Remoting_Activation_MBR_ProxyAttribute")); 
                    } 
                    pa = ca[0] as ProxyAttribute;
                } 
                Contract.Assert(pa!=null, "expect proxy attribute");

                if(!_proxyTable.Contains(serverType))
                { 
                    lock(_proxyTable)
                    { 
                        if(!_proxyTable.Contains(serverType)) 
                        {
                            // Create a new entry 
                            _proxyTable.Add(serverType, pa);
                        }
                    }
                } 
            }
 
            return pa; 
        }
 
        // Creates either an uninitialized object or a proxy depending on
        // whether the current context is OK or not.
        [System.Security.SecurityCritical]  // auto-generated
        internal static MarshalByRefObject CreateInstance(RuntimeType serverType) 
        {
            // Use our activation implementation 
            MarshalByRefObject retObj = null; 
            ConstructorCallMessage ctorCallMsg = null;
            bool bCtxOK = IsCurrentContextOK(serverType, null, ref ctorCallMsg); 
            if (bCtxOK && !serverType.IsContextful)
            {
                // Marshal by ref case
                Message.DebugOut("Allocating blank marshal-by-ref object"); 
                // We create an uninitialized instance of the actual type and
                // let the regular jit-activation execute the constructor on it. 
                retObj = RemotingServices.AllocateUninitializedObject(serverType); 
            }
            else 
            {
                //  (context not OK) || (serverType is Contextful)
                // We always return a proxy and the jit-activation's attempt
                // to execute the constructor gets intercepted by the TP stub 
                // and routed to RemotingServices.Activate() below.
 
                // if context *is* OK 
                // this is a contextBound type being activated for which
                // we always create a proxy (proxies-everywhere!) 

                // if context *is not* OK
                // this could be a MarshalByRef or ContextBound type
                // being activated outside this appDomain 
                // OR
                // this could be a ContextBound type being activated cross-ctx 
 
                RemotingProxy rp;
                // See if the object-type is configured for Connect (with a URL) 
                retObj = (MarshalByRefObject)ConnectIfNecessary(ctorCallMsg);
                if (retObj == null)
                {
                    // not configured for connect, take the usual route of 
                    // creating a proxy
                    Message.DebugOut("Creating remoting proxy for " + 
                                 serverType.FullName + " in context " + 
                                 Thread.CurrentContext);
 
                    rp = new RemotingProxy(serverType);

                    Message.DebugOut("Created remoting proxy\n");
                    retObj = (MarshalByRefObject)rp.GetTransparentProxy(); 
                }
                else 
                { 
                    Message.DebugOut("NewObj did a Connect!");
                    rp = (RemotingProxy)RemotingServices.GetRealProxy(retObj); 
                }

                // Store the constructor call message in the proxy
                rp.ConstructorMessage = ctorCallMsg; 

                if (!bCtxOK) 
                { 

                    // Chain in the context level activator now 
                    ContextLevelActivator activator = new ContextLevelActivator();
                    activator.NextActivator = ctorCallMsg.Activator;
                    ctorCallMsg.Activator = activator;
                } 
                else
                { 
                    // Set the flag to indicate that the activation 
                    // will not be leaving the client context .. in this case
                    // the default construction level activator is enough 
                    // to complete the activation process.
                    ctorCallMsg.ActivateInContext = true;
                }
            } 

            return retObj; 
        } 

        // 
        // NOTE: This is an internal method used by RemotingProxy to do Activation
        //
        // Starts off the activation chain by sending the constructor call message to
        // the activator or the client context sink chain. On return, a constructor 
        // return message is made and the out parameters are propagated.
        // 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage Activate(
            RemotingProxy remProxy, IConstructionCallMessage ctorMsg) 
        {
            IConstructionReturnMessage ctorRetMsg = null;

            if (((ConstructorCallMessage)ctorMsg).ActivateInContext) 
            {
                // The current context was approved for activation 
                Contract.Assert( 
                    ctorMsg.Activator.Level == ActivatorLevel.Construction,
                    "activator level must ActivatorLevel.Construction!"); 

                // This has to be a ContextBound type (proxies-everywhere)
                Contract.Assert(ctorMsg.ActivationType.IsContextful,
                                "Inconsistent state during activation"); 

                // Ask the activator in the message to take over 
                ctorRetMsg = ctorMsg.Activator.Activate(ctorMsg); 

                if (ctorRetMsg.Exception != null) 
                {
                    throw ctorRetMsg.Exception;
                }
            } 
            else
            { 
                // Client context was not approved for activation ... 
                Contract.Assert(
                    ctorMsg.Activator.Level >= ActivatorLevel.Context, 
                    "activator level must be at least x-context!");

                // Check with ActivationServices if we did a "Connect" with
                // a remote server during IsContextOK 
                Contract.Assert(
                    ActivationServices.CheckIfConnected(remProxy, ctorMsg) == null, 
                    "We shouldn't come through this path on a Connect."); 

                // Client context was not approved for activation ... 
                // This is the more elaborate (real) activation case i.e.
                // we have to go at least out of the client context to
                // finish the work.
 
                // Prepare for the handoff to Activation Service
 
                // Ask various attributes to contribute properties 
                // The attributes may chain in other activators into
                // the activation chain (to hijack/participate in 
                // the activation process).
                ActivationServices.GetPropertiesFromAttributes(
                    (IConstructionCallMessage)ctorMsg,
                    ctorMsg.CallSiteActivationAttributes); 

                ActivationServices.GetPropertiesFromAttributes( 
                    ctorMsg, 
                    ((ConstructorCallMessage)ctorMsg).GetWOMAttributes());
 
                ActivationServices.GetPropertiesFromAttributes(
                    (IConstructionCallMessage)ctorMsg,
                ((ConstructorCallMessage)ctorMsg).GetTypeAttributes());
 
                // Fetch the client context chain
                IMessageSink cliCtxChain = 
                Thread.CurrentContext.GetClientContextChain(); 

                // Ask the client context chain to take over from here. 
                IMethodReturnMessage retMsg =
                    (IMethodReturnMessage)
                        cliCtxChain.SyncProcessMessage(ctorMsg);
 
                // The return message may not be of type
                // IConstructionReturnMessage if an exception happens 
                // in the sink chains. 
                ctorRetMsg = retMsg as IConstructionReturnMessage;
                if (null == retMsg) 
                {
                    throw new RemotingException(
                        Environment.GetResourceString(
                            "Remoting_Activation_Failed")); 
                }
                else if (retMsg.Exception != null) 
                { 
                    throw retMsg.Exception;
                } 
            }
            // Note: PropagateOutParameters is now handled by RealProxy
            // CallContext from retMsg should be already set by RealProxy
            Contract.Assert( 
                null != ctorRetMsg,
                "Activate returning null ConstructorReturnMessage"); 
 
            return ctorRetMsg;
        } 

        // This function is called by ActivationServices in case
        // the activation needs to be within the same appdomain. These
        // are only for ContextBound types. 
        // It is also called to do satisfy remote incoming requests from
        // the activation services. These could be for both ContextBound 
        // and MarshalByRef types. 
        [System.Security.SecurityCritical]  // auto-generated
        internal static IConstructionReturnMessage DoCrossContextActivation( 
            IConstructionCallMessage reqMsg)
        {
            bool bCtxBound = reqMsg.ActivationType.IsContextful;
            Context serverContext = null; 

            if (bCtxBound) 
            { 
                // If the type is context bound, we need to create
                // the appropriate context and activate the object inside 
                // it.
                // <

                // Create a new Context 
                serverContext = new Context();
 
                // < 

 


                ArrayList list = (ArrayList) reqMsg.ContextProperties;
                RuntimeAssembly asm = null; 
                for (int i=0; i<list.Count; i++)
                { 
                    IContextProperty prop = list[i] as IContextProperty; 
                    if (null == prop)
                    { 
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_BadAttribute"));
                    } 
                    asm = (RuntimeAssembly)prop.GetType().Assembly;
                    // Make a security check to ensure that the context property 
                    // is from a trusted assembly! 
                    CheckForInfrastructurePermission(asm);
 
                    // This ensures that we don't try to add duplicate
                    // attributes (eg. type attributes common on both client
                    // and server end)
                    if (serverContext.GetProperty(prop.Name) == null) 
                    {
                        serverContext.SetProperty(prop); 
                    } 
                }
                // No more property changes to the server context from here. 
                serverContext.Freeze();

                // (This seems like an overkill but that is how it is spec-ed)
                // Ask each of the properties in the context we formed from 
                // if it is happy with the current context.
                for (int i=0; i<list.Count;i++) 
                { 
                    if (!((IContextProperty)list[i]).IsNewContextOK(
                        serverContext)) 
                    {
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_PropertyUnhappy")); 
                    }
                } 
            } 

 
            IConstructionReturnMessage  replyMsg;

            InternalCrossContextDelegate xctxDel =
                new InternalCrossContextDelegate(DoCrossContextActivationCallback); 

            Object[] args = new Object[] { reqMsg }; 
 
            if (bCtxBound)
            { 
                replyMsg = Thread.CurrentThread.InternalCrossContextCallback(
                    serverContext, xctxDel, args) as IConstructionReturnMessage;
            }
            else 
            {
                replyMsg = xctxDel(args) as IConstructionReturnMessage; 
            } 

            return replyMsg; 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal static Object DoCrossContextActivationCallback(Object[] args) 
        {
            IConstructionCallMessage    reqMsg   = (IConstructionCallMessage) args[0]; 
            IConstructionReturnMessage  replyMsg = null; 

            // call the first sink in the server context chain 
            // <
            IMethodReturnMessage retMsg =  (IMethodReturnMessage)
                    Thread.CurrentContext.GetServerContextChain().SyncProcessMessage(reqMsg);
 
            // The return message may not be of type
            // IConstructionReturnMessage if an exception happens 
            // in the sink chains. 
            Exception e = null;
            replyMsg = retMsg as IConstructionReturnMessage; 
            if (null == replyMsg)
            {
                if (retMsg != null)
                { 
                    e = retMsg.Exception;
                } 
                else 
                {
                    e = new RemotingException( 
                            Environment.GetResourceString(
                                "Remoting_Activation_Failed"));

                } 
                replyMsg = new ConstructorReturnMessage(e,null);
                // We have created our own message ... transfer the callcontext 
                // from the request message. 
                ((ConstructorReturnMessage)replyMsg).SetLogicalCallContext(
                        (LogicalCallContext) 
                        reqMsg.Properties[Message.CallContextKey]);
            }

            return replyMsg; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage DoServerContextActivation(
            IConstructionCallMessage reqMsg) 
        {
            Contract.Assert(reqMsg!=null, "NULL ctorReqMsg");
            Exception e=null;
            Type serverType = reqMsg.ActivationType; 
            Object serverObj = ActivateWithMessage(
                                    serverType, 
                                    reqMsg, 
                                    null,
                                    out e); 

            IConstructionReturnMessage replyMsg =
                SetupConstructionReply(serverObj, reqMsg, e);
 
            Contract.Assert(replyMsg!=null, "NULL ctorRetMsg");
            return replyMsg; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage SetupConstructionReply(
            Object serverObj,
            IConstructionCallMessage ctorMsg,
            Exception e) 
        {
            IConstructionReturnMessage replyMsg = null; 
            if (e == null) 
            {
                replyMsg = 
                    new ConstructorReturnMessage(
                        (MarshalByRefObject)serverObj,
                        null,   // <
                                // if ctor-s with ref/out are supported</ 
                        0,
                        (LogicalCallContext) 
                            ctorMsg.Properties[Message.CallContextKey], 
                        ctorMsg);
            } 
            else
            {
                replyMsg = new ConstructorReturnMessage(e,null);
                // We have created our own message ... transfer the callcontext 
                // from the request message.
                ((ConstructorReturnMessage)replyMsg).SetLogicalCallContext( 
                        (LogicalCallContext) 
                            ctorMsg.Properties[Message.CallContextKey]);
 
            }
            return replyMsg;
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static Object ActivateWithMessage( 
            Type serverType, IMessage msg, ServerIdentity srvIdToBind, 
            out Exception e)
        { 
            Object server = null;
            e = null;

            // Create a blank instance! 
            server = RemotingServices.AllocateUninitializedObject(serverType);
 
            Object proxyForObject = null; 
            if (serverType.IsContextful)
            { 
                if (msg is ConstructorCallMessage)
                {
                    // If it is a strictly x-context activation then
                    // this pointer for the message is the TP that we 
                    // returned to JIT in first phase of activation
                    proxyForObject = ((ConstructorCallMessage)msg).GetThisPtr(); 
                } 
                else
                { 
                    // we are out of the app-domain, so wrap this object now
                    proxyForObject = null;
                }
 
                // This associates the proxy with the real object and sets
                // up the proxy's native context, ID etc. 
                proxyForObject = RemotingServices.Wrap( 
                                        (ContextBoundObject)server,
                                        proxyForObject, 
                                        false);
                Contract.Assert(
                    RemotingServices.IsTransparentProxy(proxyForObject),
                    "Wrapped object should be a transparent proxy"); 
            }
            else 
            { 
                // Since this is an MBR type, something really bad
                // happened if we are not in the default context 
                if (Thread.CurrentContext != Context.DefaultContext)
                {
                    throw new RemotingException(
                        Environment.GetResourceString( 
                            "Remoting_Activation_Failed"));
                } 
                // Marshal-by-ref case we just return the object 
                proxyForObject = server;
            } 

            // Create the dispatcher which will help run the CTOR
            IMessageSink dispatcher = (IMessageSink)new StackBuilderSink(proxyForObject);
 
            // This call runs the CTOR on the object
            IMethodReturnMessage retMsg = (IMethodReturnMessage) 
                                        dispatcher.SyncProcessMessage(msg); 

            if (retMsg.Exception == null) 
            {
                if (serverType.IsContextful)
                {
                    // call wrap to finish the operation. 
                    return RemotingServices.Wrap((ContextBoundObject)server);
                } 
                else 
                {
                    return server; 
                }
            }
            else
            { 
                e = retMsg.Exception;
                return null; 
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void StartListeningForRemoteRequests()
        {
            // Get the activation services set up. 
            Startup();
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 
            if (!remData.ActivatorListening) 
            {
                Object configLock = remData.ConfigLock; 
                bool fLocked = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                { 
                    Monitor.Enter(configLock, ref fLocked);
                    if (!remData.ActivatorListening) 
                    { 
                        BCLDebug.Log("Registering remoting activator");
 
                        // Marshal the object so that it is ready to take remote
                        // calls. We have to create the objref because that is when
                        // the channels start listening for requests.
                        RemotingServices.MarshalInternal( 
                            Thread.GetDomain().RemotingData.ActivationListener,
                            ActivationServiceURI, 
                            typeof(System.Runtime.Remoting.Activation.IActivator)); 

                        ServerIdentity srvID = (ServerIdentity) 
                            IdentityHolder.ResolveIdentity(ActivationServiceURI);

                        // Set Singleton to prevent lease from being created
                        srvID.SetSingletonObjectMode(); 
                        //DBG Console.WriteLine("Activator URI: = " + activatorURI);
                        remData.ActivatorListening = true; 
                    } 
                }
                finally 
                {
                    if (fLocked)
                    {
                        Monitor.Exit(configLock); 
                    }
                } 
            } 
        }
 
        // This returns the local activator
        [System.Security.SecurityCritical]  // auto-generated
        internal static IActivator GetActivator()
        { 
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData;
            if (remData.LocalActivator == null) 
            { 
                Startup();
            } 
            return (IActivator)remData.LocalActivator;
        }

        [System.Security.SecurityCritical]  // auto-generated 
        internal static void Initialize()
        { 
            GetActivator(); 
        }
 
        // This returns the attribute that takes part in every activation
        // The local activator itself exposes that functionality
        [System.Security.SecurityCritical]  // auto-generated
        internal static ContextAttribute GetGlobalAttribute() 
        {
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 
            if (remData.LocalActivator == null) 
            {
                Startup(); 
            }
            return (ContextAttribute)remData.LocalActivator;
        }
 
        // This function returns the array of custom attributes of
        // type "ContextAttribute" walking the entire class hierarchy 
        // of the serverType 
        // If duplicates are found the attribute on the more derived
        // type is kept. 
        // The return array may be sparse and is terminated by a NULL.
        [System.Security.SecurityCritical]
        internal static IContextAttribute[] GetContextAttributesForType(Type serverType)
        { 
            if (!(typeof(ContextBoundObject).IsAssignableFrom(serverType)) ||
                serverType.IsCOMObject) 
            { 
                return new ContextAttribute[0];
            } 

            Type currType = serverType;
            Object[] currAttr = null;
            int retSize = 8; 
            IContextAttribute[] retAttr = new IContextAttribute[retSize];
            int numAttr = 0; 
 

            // Obtain the custom attributes that implement 
            // IContextAttribute for this type
            currAttr = currType.GetCustomAttributes(
                                    typeof(IContextAttribute),
                                    true);  // recursively on the typeHierarchy 
            Boolean bDupe;
            foreach (IContextAttribute attr in currAttr) 
            { 
                Type attrType = attr.GetType();
                bDupe = false; 
                for (int i=0; i<numAttr; i++)
                {
                    if (attrType.Equals(retAttr[i].GetType()))
                    { 
                        bDupe = true;
                        break; 
                    } 
                }
 
                if (!bDupe)
                {
                    // We must add this attribute to our list
                    numAttr++; 

                    // Check if we have enough space to store it 
                    // Leaving one spot for a NULL value! 
                    if (numAttr > retSize-1)
                    { 
                        IContextAttribute[] newAttr = new IContextAttribute[2*retSize];
                        Array.Copy(
                            retAttr,     // srcArray
                            0,          // srcIndex 
                            newAttr,    // destArray
                            0,          // destIndex 
                            retSize);   // lengthToCopy 
                        retAttr = newAttr;
                        retSize = retSize*2; 
                    }
                    retAttr[numAttr-1] = attr;
                }
            } 

            IContextAttribute[] ctxAttr = new IContextAttribute[numAttr]; 
            Array.Copy(retAttr, ctxAttr, numAttr); 
            return ctxAttr;
        } 

        // This is called during RS.IsContextOK to check if the new XXX() is configured
        // to do a direct connect, and if it is we Connect to the URL and return
        // the proxy. In the second stage, when the constructor executes on the proxy 
        // we will make sure (in Activate) that there are no CTOR args.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object ConnectIfNecessary(IConstructionCallMessage ctorMsg) 
        {
            // If the type being instantiated is configured for Connect 
            // we would have added its URL as the connect key during
            // LocalActivator::IsContextOK

            // Look for the connect URL 
            String objURL = (String) ctorMsg.Properties[ConnectKey];
            Object proxy = null; 
            if (objURL != null) 
            {
                // Connect to the URL and return the proxy 
                proxy = RemotingServices.Connect(
                                        ctorMsg.ActivationType,
                                        objURL);
            } 

            // If the type is not setup for connecting we return null! 
            return proxy; 
        }
 
        // This is really used to distinguish between proxies for completely
        // within AppDomain activations and the ones from "Connect" during
        // the second stage (RS::Activate)
        // For the former, we have to run constructor etc and for the latter 
        // we have to check that there is no non-defaul CTOR.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object CheckIfConnected( 
            RemotingProxy proxy, IConstructionCallMessage ctorMsg)
        { 
            // If we performed a connect, we must have put the URL as
            // the connectKey in the message.
            String objURL = (String)
                            ctorMsg.Properties[ConnectKey]; 
            Object tp = null;
 
            if (objURL != null) 
            {
                // We did perform a connect during IsContextOK 
                // Just get the TP from RP and return it.
                tp = (Object)proxy.GetTransparentProxy();
            }
            // We return null if we do not recognize this proxy! 
            return tp;
        } 
 
        internal static void PushActivationAttributes(Type serverType, Object[] attributes)
        { 
            // There is one such object per thread
            if (_attributeStack == null)
            {
                _attributeStack = new ActivationAttributeStack(); 
            }
            _attributeStack.Push(serverType, attributes); 
        } 

        internal static Object[] PeekActivationAttributes(Type serverType) 
        {
            // We can get a peek w/o a prior Push (eg. activation starting
            // with NewObj)
            if (_attributeStack == null) 
            {
                return null; 
            } 
            return _attributeStack.Peek(serverType);
        } 

        internal static void PopActivationAttributes(Type serverType)
        {
            Contract.Assert(_attributeStack != null, "Pop w/o a prior Set()?"); 
            _attributeStack.Pop(serverType);
        } 
    } // class ActivationServices 

 
    // This is the local activation helper and also the Attribute
    // that gets queried about every activation
    [System.Security.SecurityCritical]  // auto-generated
    internal class LocalActivator: ContextAttribute, IActivator 
    {
        internal LocalActivator() 
            : base(ActivationServices.ActivationServiceURI) 
        {
 
        }

        // ---------------------------------------------------------------
        // ContextAttribute functionality 
        // ---------------------------------------------------------------
 
        // IContextAttribute::IsContextOK 
        // This will check if a type is configured for remote activation ...
        // We return 'false' for IsContextOK if it is. 
        [System.Security.SecurityCritical]
        public override bool IsContextOK(
            Context ctx, IConstructionCallMessage ctorMsg)
        { 

            // If the app is not using config mechanism, we don't want 
            // to intercept activation. 
            if (RemotingConfigHandler.Info == null)
            { 
                return true;
            }

            // check if this type is configured for connect 
            // (instead of remote activate)
            RuntimeType activationType = ctorMsg.ActivationType as RuntimeType; 
            if (activationType == null) 
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
 
            WellKnownClientTypeEntry wkte =
                RemotingConfigHandler.IsWellKnownClientType(activationType);
            String typeURL = (wkte == null ? null : wkte.ObjectUrl);
 
            if (typeURL != null)
            { 
                // this type does have a direct uri, we will try to connect 
                // to it during the activate call. Cache it in the message.
                ctorMsg.Properties[ActivationServices.ConnectKey] = typeURL; 
                return false;
            }
            else
            { 
                ActivatedClientTypeEntry acte =
                    RemotingConfigHandler.IsRemotelyActivatedClientType(activationType); 
 
                String appURL = null;
 
                if (acte == null)
                {
                    // This is the case where the config file had no entry for this type.
                    // We should check the callsite attributes for a URL 
                    Object[] callsiteAttributes = ctorMsg.CallSiteActivationAttributes;
                    if(null != callsiteAttributes) 
                    { 
                        for(int i = 0; i < callsiteAttributes.Length; i++)
                        { 
                            UrlAttribute attr = callsiteAttributes[i] as UrlAttribute;
                            if(null != attr)
                            {
                                appURL = attr.UrlValue; 
                            }
                        } 
                    } 

                    if(appURL == null) 
                    {
                        // We don't really care about intercepting the activation in this case.
                        return true;
                    } 
                }
                else 
                { 
                    appURL = acte.ApplicationUrl;
                } 

                // Generate the URL of the remote activator
                String activatorURL = null;
                if (!appURL.EndsWith("/", StringComparison.Ordinal)) 
                    activatorURL = appURL + "/" + ActivationServices.ActivationServiceURI;
                else 
                    activatorURL = appURL + ActivationServices.ActivationServiceURI; 

                // Mark a flag for remote activation 
                // (caching the url of the activation svc of the remote server)
                ctorMsg.Properties[ActivationServices.RemoteActivateKey] = activatorURL;
                return false;
            } 
        }
 
        // IContextAttribute::GetPropertiesForNewContext 
        [System.Security.SecurityCritical]
        public override void GetPropertiesForNewContext( 
            IConstructionCallMessage ctorMsg)
        {
            BCLDebug.Log("ActivationSvc:GlobalAttrib::GetPropForNewCtx");
            // This is called during RS::Activate .. when we are sure that 
            // activation is at least x-context and this is a real activation
            // instead of a spoofed connect underneath the "new". 
            Contract.Assert(ctorMsg!=null, "ctorMsg null?"); 
            if (ctorMsg.Properties.Contains(ActivationServices.RemoteActivateKey))
            { 
                // Means we did want to intercept activation!
                String remActivatorURL = (String)
                    ctorMsg.Properties[ActivationServices.RemoteActivateKey];
 
                AppDomainLevelActivator activator =
                    new AppDomainLevelActivator(remActivatorURL); 
                // Chain ourselves at the end of the AppDomainLevel activators 
                Contract.Assert(
                        ctorMsg.Activator != null, 
                        "Should have at least x-context activator");
                IActivator curr = ctorMsg.Activator;

                if (curr.Level < ActivatorLevel.AppDomain) 
                {
                    // Common case .. .only x-context activator(s) in chain 
                    activator.NextActivator = curr; 
                    ctorMsg.Activator = activator;
                } 
                else if (curr.NextActivator == null)
                {
                    // Only one activator but not ContextLevel ...
                    // We go at the end of the chain 
                    curr.NextActivator = activator;
                } 
                else 
                {
                    // We will have to walk the chain till the end of the last 
                    // AD activator and plug ourselves in.
                    while (curr.NextActivator.Level >= ActivatorLevel.AppDomain)
                    {
                        curr = curr.NextActivator; 
                    }
                    Contract.Assert( 
                        curr.NextActivator.Level.Equals(ActivatorLevel.Context), 
                        "bad ordering of activators!");
                    activator.NextActivator = curr.NextActivator; 
                    curr.NextActivator = activator;
                }
            }
        } 

        // --------------------------------------------------------------- 
        // IActivator functionality 
        // ----------------------------------------------------------------
        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        {
            // We are a singleton internal infrastructure object.
            [System.Security.SecurityCritical] 
            get { return null; }
            // Don't allow a set either. 
            [System.Security.SecurityCritical] 
            set { throw new InvalidOperationException(); }
        } 

        //IActivator::ActivatorLevel
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]
            get { return ActivatorLevel.AppDomain; } 
        } 

        private static MethodBase GetMethodBase(IConstructionCallMessage msg) 
        {
            MethodBase mb = msg.MethodBase;
            if(null == mb)
            { 
                BCLDebug.Trace("REMOTE", "Method missing w/name ", msg.MethodName);
                    throw new RemotingException( 
                        String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_Message_MethodMissing"), 
                            msg.MethodName,
                            msg.TypeName));
            }
 
            return mb;
        } 
 
        //IActivator::Activate
        [System.Security.SecurityCritical] 
        [System.Runtime.InteropServices.ComVisible(true)]
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg)
        { 
            // This is where the activation service hooks in to activation
            // requests. We get called as the activation message is recognized 
            // by the ClientContextTerminatorSink & routed to us. 
            //
            // NOTE: This gets called for both purely within appDomain activation 
            // and 'real' remote activation scenarios as the request goes out of
            // the client context.
            // It also gets called as an incoming remote call is routed to the
            // local activator by the remote activator object. 
            //
            BCLDebug.Log("Activation Services:: new Activate()"); 
            if (ctorMsg == null) 
            {
                throw new ArgumentNullException("ctorMsg"); 
            }
            Contract.EndContractBlock();

            // Check if we have marked this activation to go remote 
            if (ctorMsg.Properties.Contains(ActivationServices.RemoteActivateKey))
            { 
                //DBG Console.WriteLine("Attempting remote activation!"); 

                return DoRemoteActivation(ctorMsg); 
            }
            else
            {
                // We must be in either a pure cross context activation or 
                // a remote incoming activation request (in which case we
                // already checked the permission to create an instance of 
                // this type). 
                if (ctorMsg.Properties.Contains(ActivationServices.PermissionKey))
                { 
                    Type activationType = ctorMsg.ActivationType;

                    // We are on the server end of a real remote activation
                    // Create a local attribute that contributes the context 
                    // properties requested by the remote request
                    Object[] attr = null; 
                    if (activationType.IsContextful) 
                    {
                    IList cp = ctorMsg.ContextProperties; 
                    if (cp != null && cp.Count > 0)
                    {
                        RemotePropertyHolderAttribute rph = new RemotePropertyHolderAttribute(cp);
                        attr = new Object[1]; 
                        attr[0] = rph;
                    } 
                    } 
                    MethodBase mb = GetMethodBase(ctorMsg);
                    RemotingMethodCachedData methodCache = 
                                            InternalRemotingServices.GetReflectionCachedData(mb);
                    Object[] args = Message.CoerceArgs(ctorMsg, methodCache.Parameters);

                    Object server = Activator.CreateInstance( 
                        activationType,
                        args, 
                        attr); 

                    // check to see if we need to do redirection 
                    if (RemotingServices.IsClientProxy(server))
                    {
                        // The wellknown type is remoted so we must wrap the proxy
                        // with a local object. 

                        // The redirection proxy masquerades as an object of the appropriate 
                        // type, and forwards incoming messages to the actual proxy. 
                        RedirectionProxy redirectedProxy =
                            new RedirectionProxy((MarshalByRefObject)server, activationType); 
                        RemotingServices.MarshalInternal(redirectedProxy, null, activationType);

                        server = redirectedProxy;
                    } 

                    return ActivationServices.SetupConstructionReply( 
                        server, ctorMsg, null); 
                }
                else 
                {
                    BCLDebug.Log("Attempting X-Context activation!");
                    // delegate to the Activator in the message
                    return ctorMsg.Activator.Activate(ctorMsg); 
                }
            } 
        } 

 
        // This is called by the local activator during an outgoing activation
        // request.
        internal static IConstructionReturnMessage DoRemoteActivation(
            IConstructionCallMessage ctorMsg) 
        {
            Contract.Assert(ctorMsg != null, "Null ctorMsg"); 
 
            // <
 



            // < 

 
 
            BCLDebug.Log("Attempting Connection to remote activation service");
            IActivator remActivator = null; 
            String remActivatorURL = (String)
                ctorMsg.Properties[ActivationServices.RemoteActivateKey];
            try
            { 
                remActivator = (IActivator)
                    RemotingServices.Connect( 
                        typeof(System.Runtime.Remoting.Activation.IActivator), 
                        remActivatorURL);
 
            }
            catch (Exception e)
            {
                throw new RemotingException( 
                    String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString( 
                            "Remoting_Activation_ConnectFailed"), 
                        e));
            } 
            // Remove the remote activate key as its purpose is served.
            ctorMsg.Properties.Remove(ActivationServices.RemoteActivateKey);

            // Delegate the work to the remote activator 
            return remActivator.Activate(ctorMsg);
        } 
 
    }// class LocalActivator
 
    // This is the object that listens to activation requests
    internal class ActivationListener:MarshalByRefObject, IActivator
    {
        // Override lifetime services to make this object live forever... 
        [System.Security.SecurityCritical]  // auto-generated
        public override Object InitializeLifetimeService() 
        { 
           return null;
        } 

        //IActivator::NextActivator
        public virtual IActivator NextActivator
        { 
            // We are a singleton internal infrastructure object.
            [System.Security.SecurityCritical]  // auto-generated 
            get { return null; } 
            // Don't allow a set either.
            [System.Security.SecurityCritical]  // auto-generated 
            set { throw new InvalidOperationException();}
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get {return ActivatorLevel.AppDomain;}
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            BCLDebug.Log("ActivationListener: received new activation request!");
            if (ctorMsg == null || RemotingServices.IsTransparentProxy(ctorMsg)) 
            {
                throw new ArgumentNullException("ctorMsg");
            }
            Contract.EndContractBlock(); 

            // Add the permission key which distinguishes pure-cross context activation from 
            // a remote request (both of which go through DoCrossContextActivation) 
            ctorMsg.Properties[ActivationServices.PermissionKey] = "allowed";
 
            // Check to make sure that this activation type has been allowed.
            String activationTypeName = ctorMsg.ActivationTypeName;
            if (!RemotingConfigHandler.IsActivationAllowed(activationTypeName))
            { 
                throw new RemotingException(
                    String.Format( 
                        CultureInfo.CurrentCulture, Environment.GetResourceString( 
                            "Remoting_Activation_PermissionDenied"),
                        ctorMsg.ActivationTypeName)); 
            }

            Type activationType = ctorMsg.ActivationType;
            if (activationType == null) 
            {
                throw new RemotingException( 
                    String.Format( 
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"),
                        ctorMsg.ActivationTypeName)); 
            }

            // Delegate to the local activator for further work
            return ActivationServices.GetActivator().Activate(ctorMsg); 
        }
 
 
    }   // class ActivationListener
 

    // This is a lightweight object to help with the activation
    // at the appDomain level ... it delegates its work to
    // ActivationServices.LocalActivator ... which is a heavy 
    // object we can't afford to carry around in the ActivatorChain
    // (since it may get Serialized/Deserialized) 
 [Serializable] 
    // attribute .. the latter shall be turned on during Beta-2!</
    internal class AppDomainLevelActivator : IActivator 
    {
        IActivator m_NextActivator;

        // Do we need this? 
        String m_RemActivatorURL;
 
        internal AppDomainLevelActivator(String remActivatorURL) 
        {
            Contract.Assert(remActivatorURL!=null,"Bad activator URL"); 
            m_RemActivatorURL = remActivatorURL;
        }

        internal AppDomainLevelActivator(SerializationInfo info, StreamingContext context) { 
            if (info==null)
            { 
                throw new ArgumentNullException("info"); 
            }
            Contract.EndContractBlock(); 
            m_NextActivator = (IActivator) info.GetValue("m_NextActivator",typeof(IActivator));
        }

        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return m_NextActivator; }
            [System.Security.SecurityCritical]  // auto-generated 
            set { m_NextActivator = value; }
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return ActivatorLevel.AppDomain; }
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            // This function will get invoked when the ClientContextTerminator sink
            // notices that an activation request message is passed to it ... it 
            // will route the message to the Activator present inside the ctorMsg
            // (which happens to be us in this case!)

            // remove ourselves from the Activator chain 
            ctorMsg.Activator = m_NextActivator;
            return ActivationServices.GetActivator().Activate(ctorMsg); 
        } 
    }
 
    // This is a lightweight object to help with the activation
    // at the context level ...
    [Serializable]
    internal class ContextLevelActivator : IActivator 
    {
        IActivator m_NextActivator; 
        internal ContextLevelActivator() 
        {
            m_NextActivator = null; 
        }

        internal ContextLevelActivator(SerializationInfo info, StreamingContext context)
        { 
            if (info==null)
            { 
                throw new ArgumentNullException("info"); 
            }
            Contract.EndContractBlock(); 
            m_NextActivator = (IActivator) info.GetValue("m_NextActivator",typeof(IActivator));
        }

        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return m_NextActivator; }
            [System.Security.SecurityCritical]  // auto-generated 
            set { m_NextActivator = value; }
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return ActivatorLevel.Context; }
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            // remove ourselves from the Activator chain
            ctorMsg.Activator = ctorMsg.Activator.NextActivator; 

            // Delegate to remoting services to do the hard work.
            // This will create a context, enter it, run through
            // the context sink chain & then delegate to the nex 
            // activator inside the ctorMsg (quite likely to be
            // the default ConstructionLevelActivator) 
            return ActivationServices.DoCrossContextActivation(ctorMsg); 
        }
    } 

    // This is a lightweight object to help with the activation
    // at the appDomain level ... it delegates its work to
    // ActivationServices.LocalActivator ... which is a heavy 
    // object we can't afford to carry around in the ActivatorChain
    // (since it may get Serialized/Deserialized) 
    [Serializable] 
    internal class ConstructionLevelActivator : IActivator
    { 
        internal ConstructionLevelActivator()
        {

        } 

 
        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            // The construction level activator is a terminating activator
            [System.Security.SecurityCritical]  // auto-generated
            get { return null; }
            // Throw if someone attempts a set 
            [System.Security.SecurityCritical]  // auto-generated
            set { throw new InvalidOperationException(); } 
        } 

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        {
            [System.Security.SecurityCritical]  // auto-generated
            get { return ActivatorLevel.Construction; } 
        }
 
        //IActivator::Activate 
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg)
        {
            // This function will get invoked when the ClientContextTerminator sink 
            // notices that an activation request message is passed to it ... it
            // will route the message to the Activator present inside the ctorMsg 
            // (which happens to be us in this case!) 

            // remove ourselves from the Activator chain 
            ctorMsg.Activator = ctorMsg.Activator.NextActivator;
            return ActivationServices.DoServerContextActivation(ctorMsg);
        }
    } 

    // This acts as a pseudo call site attribute and transfers 
    // the context properties carried in from a remote activation request 
    // to the server side activation
    internal class RemotePropertyHolderAttribute : IContextAttribute 
    {
        IList _cp;      // incoming list of context properties
        internal RemotePropertyHolderAttribute(IList cp)
        { 
            _cp = cp;
            Contract.Assert(cp != null && cp.Count > 0,"Bad _cp?"); 
        } 
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual bool IsContextOK(Context ctx, IConstructionCallMessage msg)
        {
            // The fact that we got instantiated means some remote activation
            // has contributed non-default context properties to the ctorMsg 
            return false;
        } 
 

        // properties are collected in order from callsite, wom & type 
        // attributes ... so we get a first shot at adding properties
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
        public virtual void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg) 
        {
            for (int i=0; i<_cp.Count; i++) 
            { 
                // Just cycle through the list and add the properties to
                // the construction message. 
                // We will throw at a later stage if any of these do not
                // implement IContextProperty
                ctorMsg.ContextProperties.Add(_cp[i]);
            } 
        }
    } 
 
    // Note: One instance of this class is setup per thread that comes to
    // managed remoting for activation of MBR types. All access to methods 
    // is by design single-threaded. (Each thread is working on its own object).

    // In the case of Activator.CreateInstance ... that API does the Push &
    // Remoting does a Pop() as soon as it has picked up the attributes from 
    // the threadStatic. The CreateInstance API itself does a Pop() too in
    // a try-finally. (So this does not work very well if the infrastructure 
    // creates an instance of the same MBR type as the outer type being created. 
    // However, to minimize code churn this is the least risky fix we can do.
    // The full fix would be to pass activationAttributes into the VM through 
    // reflection code and have the VM pass them over to remoting which will
    // then hand them over to managed remoting helpers. This will also involve
    // adding attributes as an additional parameter to
    // ProxyAttribute.CreateInstance() public method. 

    internal class ActivationAttributeStack 
    { 
        Object[] activationTypes;
        Object[] activationAttributes; 
        int freeIndex;
        internal ActivationAttributeStack()
        {
            activationTypes = new Object[4]; 
            activationAttributes = new Object[4];
            freeIndex = 0; 
        } 

        internal void Push(Type typ, Object[] attr) 
        {
            Contract.Assert(typ!=null, "typ != null");
            Contract.Assert(attr!=null, "attr != null");
 
            if (freeIndex == activationTypes.Length)
            { 
                // Need to grow our arrays ... this will be exceedingly rare 
                Object[] newTypes = new Object[activationTypes.Length * 2];
                Object[] newAttr = new Object[activationAttributes.Length * 2]; 
                Contract.Assert(newAttr.Length == newTypes.Length,"These should be in [....]!");
                Array.Copy(activationTypes, newTypes, activationTypes.Length);
                Array.Copy(activationAttributes, newAttr, activationAttributes.Length);
                activationTypes = newTypes; 
                activationAttributes = newAttr;
            } 
            activationTypes[freeIndex] = typ; 
            activationAttributes[freeIndex] = attr;
            freeIndex++; 
        }

        internal Object[] Peek(Type typ)
        { 
            Contract.Assert(typ!=null, "typ != null");
            if (freeIndex == 0 || activationTypes[freeIndex-1] != (object)typ) 
            { 
                return null;
            } 
            return (Object[])activationAttributes[freeIndex-1];
        }

        // Note: Read the comments above .. you can have 2 pops for the same 
        // push. We also count on infrastructure code not activating
        // the same type as the caller causing a recursive activation. 
        internal void Pop(Type typ) 
        {
            Contract.Assert(typ!=null, "typ != null"); 
            if (freeIndex != 0 && activationTypes[freeIndex-1] == (object)typ)
            {
                freeIndex--;
                // Clear the popped entry 
                activationTypes[freeIndex] = null;
                activationAttributes[freeIndex] = null; 
            } 
        }
    } 
}//namespace

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
**  File:    ActivationServices.cs 
**
**  Author(s): 
**
**  Purpose:
**
** 
===========================================================*/
namespace System.Runtime.Remoting.Activation { 
 
    using System;
    using System.Security; 
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Contexts; 
    using System.Runtime.Remoting.Proxies;
    using System.Runtime.Remoting.Messaging; 
    using System.Runtime.Remoting.Metadata; 
    using System.Collections;
    using System.Reflection; 
    using System.IO;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Runtime.CompilerServices;
    using System.Diagnostics.Contracts; 
 
    // Implements various activation services
    internal static class ActivationServices 
    {

        private static IActivator activator = null;
 
        private static Hashtable _proxyTable = new Hashtable();
        private static Type proxyAttributeType = typeof(System.Runtime.Remoting.Proxies.ProxyAttribute); 
        [System.Security.SecurityCritical /*auto-generated*/] 
        private static ProxyAttribute _proxyAttribute = new ProxyAttribute();
        [ThreadStaticAttribute()] 
        internal static ActivationAttributeStack _attributeStack;

        internal const String ActivationServiceURI = "RemoteActivationService.rem";
 
        internal const String RemoteActivateKey = "Remote";
        internal const String PermissionKey = "Permission"; 
        internal const String ConnectKey = "Connect"; 

        [System.Security.SecuritySafeCritical] // static constructors should be safe to call 
        static ActivationServices()
        { }

        // < 

 
 

 
        //1 private static LocalActivator  localActivator = null;

        // ActivationListener is the object that listens to incoming
        // activation requests. It delegates the incoming request to 
        // the local activator.
        //2 private static ActivationListener ActivationListener = null; 
 
        //3 private static Object staticSyncObject = new Object();
        //4 private static bool bInitializing = false; 

        // This gets called upon the first attempt to activate
        // anything that is ContextBound or MarshalByRef
        [System.Security.SecurityCritical]  // auto-generated 
        private static void Startup()
        { 
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 

            // wait on the lock if a)activation has not been initialized yet 
            // or b) activation is being initialized by another thread!
            if ((!remData.ActivationInitialized)
               || remData.InitializingActivation)
            { 
                Object configLock = remData.ConfigLock;
                bool fLocked = false; 
                RuntimeHelpers.PrepareConstrainedRegions(); 
                try
                { 
                    Monitor.Enter(configLock, ref fLocked);
                    remData.InitializingActivation = true;
                    // Ensure that some other thread did not complete
                    // the work while we were waiting on the lock. 
                    if (!remData.ActivationInitialized)
                    { 
                        // Startup the activation service 
                        BCLDebug.Trace("REMOTE","Starting up activation service ",Thread.CurrentContext);
 
                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                        // NOTE: This should be the first step in Startup!
                        // Otherwise activation will recurse, when we try
                        // to create the ActivationListener (which is MarshalByRef) 
                        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                        remData.LocalActivator = new LocalActivator(); 
 
                        // Add the Lifetime service property to the appdomain.
                        // For now we are assuming that this is the only property 
                        // If there are more properties, then an existing array
                        // will need to be expanded to add this property

                        // This is activated in RemotingServices.DomainSpecificRemotingData() 
                        // IContextProperty[] contextProperties = new IContextProperty[1];
                        // contextProperties[0] = new System.Runtime.Remoting.LeaseLifeTimeServiceProperty(); 
                        // Thread.GetDomain().RemotingData.AppDomainContextProperties = contextProperties; 

                        remData.ActivationListener = new ActivationListener(); 
                        remData.ActivationInitialized = true;

                    }
 
                    remData.InitializingActivation = false;
                } //lock (remData) 
                finally 
                {
                    if (fLocked) 
                    {
                        Monitor.Exit(configLock);
                    }
                } 
            }
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        private static void InitActivationServices() 
        {
            // If activation services has not been loaded do it now and create
            // the instace that will service the activation requests.
            if (null == activator) 
            {
                activator = GetActivator(); 
                if (null == activator) 
                {
                    Message.DebugOut("Fatal Error... Could not create activator\n"); 
                    throw new RemotingException(
                        String.Format(
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_BadInternalState_ActivationFailure"))); 
                }
            } 
        } 

        // Determine whether the current context is ok for the activation. 
        [System.Security.SecurityCritical]  // auto-generated
        private static MarshalByRefObject IsCurrentContextOK(
            RuntimeType serverType, Object[] props, bool bNewObj)
        { 
            Contract.Assert(!serverType.IsInterface,"!serverType.IsInterface");
 
            MarshalByRefObject retObj = null; 

            // Initialize activation services if needed. 
            //   (we temporary null out the activation attributes in case
            //    InitActivationServices creates an MBR).
            InitActivationServices();
 
            // Obtain the method info which will create an instance
            // of type RealProxy 
            ProxyAttribute pa = GetProxyAttribute(serverType); 
            Contract.Assert(null != pa, "null != pa");
 
            if (Object.ReferenceEquals(pa, DefaultProxyAttribute))
                retObj = pa.CreateInstanceInternal(serverType);
            else
            { 
                retObj = pa.CreateInstance(serverType);
                // We called a custom proxy attribute .. make sure it is 
                // returning a server of the correct type. 
                if (retObj != null)
                { 
                    // If a transparent proxy is returned we are fine.
                    // If not then the object's type MUST be compatible
                    // with the type we were requested to activate!
                    if (!RemotingServices.IsTransparentProxy(retObj) 
                        && !serverType.IsAssignableFrom(retObj.GetType()))
                    { 
                        throw new RemotingException( 
                            String.Format(
                                CultureInfo.CurrentCulture, Environment.GetResourceString( 
                                    "Remoting_Activation_BadObject"),
                            serverType));
                    }
                } 
            }
            Contract.Assert(null != retObj, "null != retObj"); 
            return retObj; 
        }
 
#if FEATURE_COMINTEROP
        [System.Security.SecurityCritical]  // auto-generated
        private static MarshalByRefObject CreateObjectForCom(
            RuntimeType serverType, Object[] props, bool bNewObj) 
        {
            Contract.Assert(!serverType.IsInterface,"!serverType.IsInterface"); 
 
            MarshalByRefObject retObj = null;
 
            if (PeekActivationAttributes(serverType) != null)
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_ActivForCom" ));

            // Initialize activation services if needed 
            InitActivationServices();
 
            // Obtain the method info which will create an instance 
            // of type RealProxy
            ProxyAttribute pa = GetProxyAttribute(serverType); 
            Contract.Assert(null != pa, "null != pa");

            if(pa is ICustomFactory)
            { 
                retObj = ((ICustomFactory)pa).CreateInstance(serverType);
            } 
            else 
            {
                retObj = (MarshalByRefObject)Activator.CreateInstance(serverType, true); 
            }

            Contract.Assert(null != retObj, "null != retObj");
            return retObj; 
        }
#endif // FEATURE_COMINTEROP 
 
        // For types with no proxy attribute, we take the default route of
        // querying attributes if the current context is suitable for 
        // activation.
        [System.Security.SecurityCritical]  // auto-generated
        private static bool IsCurrentContextOK(RuntimeType serverType, Object[] props,
                                               ref ConstructorCallMessage ctorCallMsg) 
        {
             //Get callSite attributes 
            Object[] callSiteAttr = PeekActivationAttributes(serverType); 

            // Clear from the attribute stack 
            if (callSiteAttr != null)
            {
                PopActivationAttributes(serverType);
            } 

            Object[] womAttr = new Object[1]; 
            womAttr[0] = GetGlobalAttribute(); 

            // Get the type context attributes 
            Object[] typeAttr = GetContextAttributesForType(serverType);

            // Get the client context (current context)
            Context cliCtx = Thread.CurrentContext; 

            // Create a ctorCallMsg with the reqd info 
            ctorCallMsg = 
                new ConstructorCallMessage(
                    callSiteAttr, 
                    womAttr,
                    typeAttr,
                    serverType);
 
            // This is the activator that handles activation in *all* cases
            // Based on whether what the activation attributes do.... other 
            // activators may get chained ahead of this one and may take 
            // over the activation process... (possibly) delegating to this
            // only in the last stage. 
            // Note: currently, this does not get used in the same context (MBR)
            // scenarios ... because of the 2-step activation model of JIT.
            ctorCallMsg.Activator = new ConstructionLevelActivator();
 

            // Ask all attributes if they are happy with the current context 
            // NOTE: if someone says no, we do not ask the rest of the attributes 
            // This is why, womAttr (which is the global activation service
            // attribute) *must* be the first one we query. 
            bool bCtxOK = QueryAttributesIfContextOK(cliCtx,
                                                     ctorCallMsg,
                                                     womAttr);
            if (bCtxOK == true) 
            {
                bCtxOK = QueryAttributesIfContextOK(cliCtx, 
                                                    ctorCallMsg, 
                                                    callSiteAttr);
                if (bCtxOK == true) 
                {
                    bCtxOK = QueryAttributesIfContextOK(cliCtx,
                                                        ctorCallMsg,
                                                        typeAttr); 
                }
            } 
 
            return bCtxOK;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        private static void CheckForInfrastructurePermission(RuntimeAssembly asm)
        { 
            // Make a security check to ensure that the context attribute
            // is from a trusted assembly! 
            if (asm != RemotingServices.s_MscorlibAssembly) 
            {
                CodeAccessSecurityEngine.CheckAssembly(asm, RemotingServices.s_RemotingInfrastructurePermission); 
            }
        }

        [System.Security.SecurityCritical]  // auto-generated 
        private static bool QueryAttributesIfContextOK(
            Context ctx, IConstructionCallMessage ctorMsg, Object[] attributes) 
        { 
            bool bCtxOK = true;
            if (attributes != null) 
            {
                for (int i=0; i<attributes.Length; i++)
                {
                    // All the attributes, including callsite attributes should 
                    // expose IContextAttribute. If not, then we throw an
                    // exception. 
                    IContextAttribute attr = attributes[i] as IContextAttribute; 
                    if(null != attr)
                    { 
                        RuntimeAssembly asm = (RuntimeAssembly)attr.GetType().Assembly;
                        // Make a security check to ensure that the context attribute
                        // is from a trusted assembly!
                        CheckForInfrastructurePermission(asm); 

                        bCtxOK = attr.IsContextOK(ctx, ctorMsg); 
                        if (bCtxOK == false) 
                        {
                            break; 
                        }
                    }
                    else
                    { 
                        throw new RemotingException(
                                Environment.GetResourceString( 
                                    "Remoting_Activation_BadAttribute")); 
                    }
                } 
            }
            return bCtxOK;
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void GetPropertiesFromAttributes( 
            IConstructionCallMessage ctorMsg, Object[] attributes) 
        {
            if (attributes != null) 
            {
                for (int i=0; i<attributes.Length; i++)
                {
                    // All the attributes, including callsite attributes should 
                    // expose IContextAttribute. If not, then we throw an
                    // exception. 
                    IContextAttribute attr = attributes[i] as IContextAttribute; 
                    if(null != attr)
                    { 
                        RuntimeAssembly asm = (RuntimeAssembly)attr.GetType().Assembly;
                        // Make a security check to ensure that the context attribute
                        // is from a trusted assembly!
                        CheckForInfrastructurePermission(asm); 

                        // We ask each attribute to contribute its properties. 
                        // The attributes can examine the current list of properties 
                        // from the ctorCallMsg and decide which properties to add.
 
                        // They can also tweak the Activator chain during this process
                        attr.GetPropertiesForNewContext(ctorMsg);
                    }
                    else 
                    {
                        throw new RemotingException( 
                            Environment.GetResourceString( 
                                "Remoting_Activation_BadAttribute"));
                    } 
                }
            }
        }
 
        // Return the default implementation of the proxy attribute
        internal static ProxyAttribute DefaultProxyAttribute 
        { 
            [System.Security.SecurityCritical]  // auto-generated
            get { return _proxyAttribute; } 
        }

        // Iterate over the custom attributes of the class and see if it
        // defines a ProxyAttribute. If one is not defined then return 
        // the default proxy attribute defined by us.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static ProxyAttribute GetProxyAttribute(Type serverType) 
        {
 
            Contract.Assert(
                serverType.IsMarshalByRef,
                "type should be at least marshal-by-ref");
 
            if (!serverType.HasProxyAttribute)
                return DefaultProxyAttribute; 
 
            // Type has a non-default proxy attribute ... see if we have
            // it cached? 
            ProxyAttribute pa = _proxyTable[serverType] as ProxyAttribute;

            if (pa == null)
            { 
                Object[] ca = Attribute.GetCustomAttributes(
                                            serverType, 
                                            proxyAttributeType, 
                                            true);
                if((null != ca) && (0 != ca.Length)) 
                {
                    if (!serverType.IsContextful)
                    {
                        throw new RemotingException( 
                                    Environment.GetResourceString(
                                    "Remoting_Activation_MBR_ProxyAttribute")); 
                    } 
                    pa = ca[0] as ProxyAttribute;
                } 
                Contract.Assert(pa!=null, "expect proxy attribute");

                if(!_proxyTable.Contains(serverType))
                { 
                    lock(_proxyTable)
                    { 
                        if(!_proxyTable.Contains(serverType)) 
                        {
                            // Create a new entry 
                            _proxyTable.Add(serverType, pa);
                        }
                    }
                } 
            }
 
            return pa; 
        }
 
        // Creates either an uninitialized object or a proxy depending on
        // whether the current context is OK or not.
        [System.Security.SecurityCritical]  // auto-generated
        internal static MarshalByRefObject CreateInstance(RuntimeType serverType) 
        {
            // Use our activation implementation 
            MarshalByRefObject retObj = null; 
            ConstructorCallMessage ctorCallMsg = null;
            bool bCtxOK = IsCurrentContextOK(serverType, null, ref ctorCallMsg); 
            if (bCtxOK && !serverType.IsContextful)
            {
                // Marshal by ref case
                Message.DebugOut("Allocating blank marshal-by-ref object"); 
                // We create an uninitialized instance of the actual type and
                // let the regular jit-activation execute the constructor on it. 
                retObj = RemotingServices.AllocateUninitializedObject(serverType); 
            }
            else 
            {
                //  (context not OK) || (serverType is Contextful)
                // We always return a proxy and the jit-activation's attempt
                // to execute the constructor gets intercepted by the TP stub 
                // and routed to RemotingServices.Activate() below.
 
                // if context *is* OK 
                // this is a contextBound type being activated for which
                // we always create a proxy (proxies-everywhere!) 

                // if context *is not* OK
                // this could be a MarshalByRef or ContextBound type
                // being activated outside this appDomain 
                // OR
                // this could be a ContextBound type being activated cross-ctx 
 
                RemotingProxy rp;
                // See if the object-type is configured for Connect (with a URL) 
                retObj = (MarshalByRefObject)ConnectIfNecessary(ctorCallMsg);
                if (retObj == null)
                {
                    // not configured for connect, take the usual route of 
                    // creating a proxy
                    Message.DebugOut("Creating remoting proxy for " + 
                                 serverType.FullName + " in context " + 
                                 Thread.CurrentContext);
 
                    rp = new RemotingProxy(serverType);

                    Message.DebugOut("Created remoting proxy\n");
                    retObj = (MarshalByRefObject)rp.GetTransparentProxy(); 
                }
                else 
                { 
                    Message.DebugOut("NewObj did a Connect!");
                    rp = (RemotingProxy)RemotingServices.GetRealProxy(retObj); 
                }

                // Store the constructor call message in the proxy
                rp.ConstructorMessage = ctorCallMsg; 

                if (!bCtxOK) 
                { 

                    // Chain in the context level activator now 
                    ContextLevelActivator activator = new ContextLevelActivator();
                    activator.NextActivator = ctorCallMsg.Activator;
                    ctorCallMsg.Activator = activator;
                } 
                else
                { 
                    // Set the flag to indicate that the activation 
                    // will not be leaving the client context .. in this case
                    // the default construction level activator is enough 
                    // to complete the activation process.
                    ctorCallMsg.ActivateInContext = true;
                }
            } 

            return retObj; 
        } 

        // 
        // NOTE: This is an internal method used by RemotingProxy to do Activation
        //
        // Starts off the activation chain by sending the constructor call message to
        // the activator or the client context sink chain. On return, a constructor 
        // return message is made and the out parameters are propagated.
        // 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage Activate(
            RemotingProxy remProxy, IConstructionCallMessage ctorMsg) 
        {
            IConstructionReturnMessage ctorRetMsg = null;

            if (((ConstructorCallMessage)ctorMsg).ActivateInContext) 
            {
                // The current context was approved for activation 
                Contract.Assert( 
                    ctorMsg.Activator.Level == ActivatorLevel.Construction,
                    "activator level must ActivatorLevel.Construction!"); 

                // This has to be a ContextBound type (proxies-everywhere)
                Contract.Assert(ctorMsg.ActivationType.IsContextful,
                                "Inconsistent state during activation"); 

                // Ask the activator in the message to take over 
                ctorRetMsg = ctorMsg.Activator.Activate(ctorMsg); 

                if (ctorRetMsg.Exception != null) 
                {
                    throw ctorRetMsg.Exception;
                }
            } 
            else
            { 
                // Client context was not approved for activation ... 
                Contract.Assert(
                    ctorMsg.Activator.Level >= ActivatorLevel.Context, 
                    "activator level must be at least x-context!");

                // Check with ActivationServices if we did a "Connect" with
                // a remote server during IsContextOK 
                Contract.Assert(
                    ActivationServices.CheckIfConnected(remProxy, ctorMsg) == null, 
                    "We shouldn't come through this path on a Connect."); 

                // Client context was not approved for activation ... 
                // This is the more elaborate (real) activation case i.e.
                // we have to go at least out of the client context to
                // finish the work.
 
                // Prepare for the handoff to Activation Service
 
                // Ask various attributes to contribute properties 
                // The attributes may chain in other activators into
                // the activation chain (to hijack/participate in 
                // the activation process).
                ActivationServices.GetPropertiesFromAttributes(
                    (IConstructionCallMessage)ctorMsg,
                    ctorMsg.CallSiteActivationAttributes); 

                ActivationServices.GetPropertiesFromAttributes( 
                    ctorMsg, 
                    ((ConstructorCallMessage)ctorMsg).GetWOMAttributes());
 
                ActivationServices.GetPropertiesFromAttributes(
                    (IConstructionCallMessage)ctorMsg,
                ((ConstructorCallMessage)ctorMsg).GetTypeAttributes());
 
                // Fetch the client context chain
                IMessageSink cliCtxChain = 
                Thread.CurrentContext.GetClientContextChain(); 

                // Ask the client context chain to take over from here. 
                IMethodReturnMessage retMsg =
                    (IMethodReturnMessage)
                        cliCtxChain.SyncProcessMessage(ctorMsg);
 
                // The return message may not be of type
                // IConstructionReturnMessage if an exception happens 
                // in the sink chains. 
                ctorRetMsg = retMsg as IConstructionReturnMessage;
                if (null == retMsg) 
                {
                    throw new RemotingException(
                        Environment.GetResourceString(
                            "Remoting_Activation_Failed")); 
                }
                else if (retMsg.Exception != null) 
                { 
                    throw retMsg.Exception;
                } 
            }
            // Note: PropagateOutParameters is now handled by RealProxy
            // CallContext from retMsg should be already set by RealProxy
            Contract.Assert( 
                null != ctorRetMsg,
                "Activate returning null ConstructorReturnMessage"); 
 
            return ctorRetMsg;
        } 

        // This function is called by ActivationServices in case
        // the activation needs to be within the same appdomain. These
        // are only for ContextBound types. 
        // It is also called to do satisfy remote incoming requests from
        // the activation services. These could be for both ContextBound 
        // and MarshalByRef types. 
        [System.Security.SecurityCritical]  // auto-generated
        internal static IConstructionReturnMessage DoCrossContextActivation( 
            IConstructionCallMessage reqMsg)
        {
            bool bCtxBound = reqMsg.ActivationType.IsContextful;
            Context serverContext = null; 

            if (bCtxBound) 
            { 
                // If the type is context bound, we need to create
                // the appropriate context and activate the object inside 
                // it.
                // <

                // Create a new Context 
                serverContext = new Context();
 
                // < 

 


                ArrayList list = (ArrayList) reqMsg.ContextProperties;
                RuntimeAssembly asm = null; 
                for (int i=0; i<list.Count; i++)
                { 
                    IContextProperty prop = list[i] as IContextProperty; 
                    if (null == prop)
                    { 
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_BadAttribute"));
                    } 
                    asm = (RuntimeAssembly)prop.GetType().Assembly;
                    // Make a security check to ensure that the context property 
                    // is from a trusted assembly! 
                    CheckForInfrastructurePermission(asm);
 
                    // This ensures that we don't try to add duplicate
                    // attributes (eg. type attributes common on both client
                    // and server end)
                    if (serverContext.GetProperty(prop.Name) == null) 
                    {
                        serverContext.SetProperty(prop); 
                    } 
                }
                // No more property changes to the server context from here. 
                serverContext.Freeze();

                // (This seems like an overkill but that is how it is spec-ed)
                // Ask each of the properties in the context we formed from 
                // if it is happy with the current context.
                for (int i=0; i<list.Count;i++) 
                { 
                    if (!((IContextProperty)list[i]).IsNewContextOK(
                        serverContext)) 
                    {
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_PropertyUnhappy")); 
                    }
                } 
            } 

 
            IConstructionReturnMessage  replyMsg;

            InternalCrossContextDelegate xctxDel =
                new InternalCrossContextDelegate(DoCrossContextActivationCallback); 

            Object[] args = new Object[] { reqMsg }; 
 
            if (bCtxBound)
            { 
                replyMsg = Thread.CurrentThread.InternalCrossContextCallback(
                    serverContext, xctxDel, args) as IConstructionReturnMessage;
            }
            else 
            {
                replyMsg = xctxDel(args) as IConstructionReturnMessage; 
            } 

            return replyMsg; 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal static Object DoCrossContextActivationCallback(Object[] args) 
        {
            IConstructionCallMessage    reqMsg   = (IConstructionCallMessage) args[0]; 
            IConstructionReturnMessage  replyMsg = null; 

            // call the first sink in the server context chain 
            // <
            IMethodReturnMessage retMsg =  (IMethodReturnMessage)
                    Thread.CurrentContext.GetServerContextChain().SyncProcessMessage(reqMsg);
 
            // The return message may not be of type
            // IConstructionReturnMessage if an exception happens 
            // in the sink chains. 
            Exception e = null;
            replyMsg = retMsg as IConstructionReturnMessage; 
            if (null == replyMsg)
            {
                if (retMsg != null)
                { 
                    e = retMsg.Exception;
                } 
                else 
                {
                    e = new RemotingException( 
                            Environment.GetResourceString(
                                "Remoting_Activation_Failed"));

                } 
                replyMsg = new ConstructorReturnMessage(e,null);
                // We have created our own message ... transfer the callcontext 
                // from the request message. 
                ((ConstructorReturnMessage)replyMsg).SetLogicalCallContext(
                        (LogicalCallContext) 
                        reqMsg.Properties[Message.CallContextKey]);
            }

            return replyMsg; 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage DoServerContextActivation(
            IConstructionCallMessage reqMsg) 
        {
            Contract.Assert(reqMsg!=null, "NULL ctorReqMsg");
            Exception e=null;
            Type serverType = reqMsg.ActivationType; 
            Object serverObj = ActivateWithMessage(
                                    serverType, 
                                    reqMsg, 
                                    null,
                                    out e); 

            IConstructionReturnMessage replyMsg =
                SetupConstructionReply(serverObj, reqMsg, e);
 
            Contract.Assert(replyMsg!=null, "NULL ctorRetMsg");
            return replyMsg; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        internal static IConstructionReturnMessage SetupConstructionReply(
            Object serverObj,
            IConstructionCallMessage ctorMsg,
            Exception e) 
        {
            IConstructionReturnMessage replyMsg = null; 
            if (e == null) 
            {
                replyMsg = 
                    new ConstructorReturnMessage(
                        (MarshalByRefObject)serverObj,
                        null,   // <
                                // if ctor-s with ref/out are supported</ 
                        0,
                        (LogicalCallContext) 
                            ctorMsg.Properties[Message.CallContextKey], 
                        ctorMsg);
            } 
            else
            {
                replyMsg = new ConstructorReturnMessage(e,null);
                // We have created our own message ... transfer the callcontext 
                // from the request message.
                ((ConstructorReturnMessage)replyMsg).SetLogicalCallContext( 
                        (LogicalCallContext) 
                            ctorMsg.Properties[Message.CallContextKey]);
 
            }
            return replyMsg;
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static Object ActivateWithMessage( 
            Type serverType, IMessage msg, ServerIdentity srvIdToBind, 
            out Exception e)
        { 
            Object server = null;
            e = null;

            // Create a blank instance! 
            server = RemotingServices.AllocateUninitializedObject(serverType);
 
            Object proxyForObject = null; 
            if (serverType.IsContextful)
            { 
                if (msg is ConstructorCallMessage)
                {
                    // If it is a strictly x-context activation then
                    // this pointer for the message is the TP that we 
                    // returned to JIT in first phase of activation
                    proxyForObject = ((ConstructorCallMessage)msg).GetThisPtr(); 
                } 
                else
                { 
                    // we are out of the app-domain, so wrap this object now
                    proxyForObject = null;
                }
 
                // This associates the proxy with the real object and sets
                // up the proxy's native context, ID etc. 
                proxyForObject = RemotingServices.Wrap( 
                                        (ContextBoundObject)server,
                                        proxyForObject, 
                                        false);
                Contract.Assert(
                    RemotingServices.IsTransparentProxy(proxyForObject),
                    "Wrapped object should be a transparent proxy"); 
            }
            else 
            { 
                // Since this is an MBR type, something really bad
                // happened if we are not in the default context 
                if (Thread.CurrentContext != Context.DefaultContext)
                {
                    throw new RemotingException(
                        Environment.GetResourceString( 
                            "Remoting_Activation_Failed"));
                } 
                // Marshal-by-ref case we just return the object 
                proxyForObject = server;
            } 

            // Create the dispatcher which will help run the CTOR
            IMessageSink dispatcher = (IMessageSink)new StackBuilderSink(proxyForObject);
 
            // This call runs the CTOR on the object
            IMethodReturnMessage retMsg = (IMethodReturnMessage) 
                                        dispatcher.SyncProcessMessage(msg); 

            if (retMsg.Exception == null) 
            {
                if (serverType.IsContextful)
                {
                    // call wrap to finish the operation. 
                    return RemotingServices.Wrap((ContextBoundObject)server);
                } 
                else 
                {
                    return server; 
                }
            }
            else
            { 
                e = retMsg.Exception;
                return null; 
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static void StartListeningForRemoteRequests()
        {
            // Get the activation services set up. 
            Startup();
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 
            if (!remData.ActivatorListening) 
            {
                Object configLock = remData.ConfigLock; 
                bool fLocked = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                { 
                    Monitor.Enter(configLock, ref fLocked);
                    if (!remData.ActivatorListening) 
                    { 
                        BCLDebug.Log("Registering remoting activator");
 
                        // Marshal the object so that it is ready to take remote
                        // calls. We have to create the objref because that is when
                        // the channels start listening for requests.
                        RemotingServices.MarshalInternal( 
                            Thread.GetDomain().RemotingData.ActivationListener,
                            ActivationServiceURI, 
                            typeof(System.Runtime.Remoting.Activation.IActivator)); 

                        ServerIdentity srvID = (ServerIdentity) 
                            IdentityHolder.ResolveIdentity(ActivationServiceURI);

                        // Set Singleton to prevent lease from being created
                        srvID.SetSingletonObjectMode(); 
                        //DBG Console.WriteLine("Activator URI: = " + activatorURI);
                        remData.ActivatorListening = true; 
                    } 
                }
                finally 
                {
                    if (fLocked)
                    {
                        Monitor.Exit(configLock); 
                    }
                } 
            } 
        }
 
        // This returns the local activator
        [System.Security.SecurityCritical]  // auto-generated
        internal static IActivator GetActivator()
        { 
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData;
            if (remData.LocalActivator == null) 
            { 
                Startup();
            } 
            return (IActivator)remData.LocalActivator;
        }

        [System.Security.SecurityCritical]  // auto-generated 
        internal static void Initialize()
        { 
            GetActivator(); 
        }
 
        // This returns the attribute that takes part in every activation
        // The local activator itself exposes that functionality
        [System.Security.SecurityCritical]  // auto-generated
        internal static ContextAttribute GetGlobalAttribute() 
        {
            DomainSpecificRemotingData remData = Thread.GetDomain().RemotingData; 
            if (remData.LocalActivator == null) 
            {
                Startup(); 
            }
            return (ContextAttribute)remData.LocalActivator;
        }
 
        // This function returns the array of custom attributes of
        // type "ContextAttribute" walking the entire class hierarchy 
        // of the serverType 
        // If duplicates are found the attribute on the more derived
        // type is kept. 
        // The return array may be sparse and is terminated by a NULL.
        [System.Security.SecurityCritical]
        internal static IContextAttribute[] GetContextAttributesForType(Type serverType)
        { 
            if (!(typeof(ContextBoundObject).IsAssignableFrom(serverType)) ||
                serverType.IsCOMObject) 
            { 
                return new ContextAttribute[0];
            } 

            Type currType = serverType;
            Object[] currAttr = null;
            int retSize = 8; 
            IContextAttribute[] retAttr = new IContextAttribute[retSize];
            int numAttr = 0; 
 

            // Obtain the custom attributes that implement 
            // IContextAttribute for this type
            currAttr = currType.GetCustomAttributes(
                                    typeof(IContextAttribute),
                                    true);  // recursively on the typeHierarchy 
            Boolean bDupe;
            foreach (IContextAttribute attr in currAttr) 
            { 
                Type attrType = attr.GetType();
                bDupe = false; 
                for (int i=0; i<numAttr; i++)
                {
                    if (attrType.Equals(retAttr[i].GetType()))
                    { 
                        bDupe = true;
                        break; 
                    } 
                }
 
                if (!bDupe)
                {
                    // We must add this attribute to our list
                    numAttr++; 

                    // Check if we have enough space to store it 
                    // Leaving one spot for a NULL value! 
                    if (numAttr > retSize-1)
                    { 
                        IContextAttribute[] newAttr = new IContextAttribute[2*retSize];
                        Array.Copy(
                            retAttr,     // srcArray
                            0,          // srcIndex 
                            newAttr,    // destArray
                            0,          // destIndex 
                            retSize);   // lengthToCopy 
                        retAttr = newAttr;
                        retSize = retSize*2; 
                    }
                    retAttr[numAttr-1] = attr;
                }
            } 

            IContextAttribute[] ctxAttr = new IContextAttribute[numAttr]; 
            Array.Copy(retAttr, ctxAttr, numAttr); 
            return ctxAttr;
        } 

        // This is called during RS.IsContextOK to check if the new XXX() is configured
        // to do a direct connect, and if it is we Connect to the URL and return
        // the proxy. In the second stage, when the constructor executes on the proxy 
        // we will make sure (in Activate) that there are no CTOR args.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object ConnectIfNecessary(IConstructionCallMessage ctorMsg) 
        {
            // If the type being instantiated is configured for Connect 
            // we would have added its URL as the connect key during
            // LocalActivator::IsContextOK

            // Look for the connect URL 
            String objURL = (String) ctorMsg.Properties[ConnectKey];
            Object proxy = null; 
            if (objURL != null) 
            {
                // Connect to the URL and return the proxy 
                proxy = RemotingServices.Connect(
                                        ctorMsg.ActivationType,
                                        objURL);
            } 

            // If the type is not setup for connecting we return null! 
            return proxy; 
        }
 
        // This is really used to distinguish between proxies for completely
        // within AppDomain activations and the ones from "Connect" during
        // the second stage (RS::Activate)
        // For the former, we have to run constructor etc and for the latter 
        // we have to check that there is no non-defaul CTOR.
        [System.Security.SecurityCritical]  // auto-generated 
        internal static Object CheckIfConnected( 
            RemotingProxy proxy, IConstructionCallMessage ctorMsg)
        { 
            // If we performed a connect, we must have put the URL as
            // the connectKey in the message.
            String objURL = (String)
                            ctorMsg.Properties[ConnectKey]; 
            Object tp = null;
 
            if (objURL != null) 
            {
                // We did perform a connect during IsContextOK 
                // Just get the TP from RP and return it.
                tp = (Object)proxy.GetTransparentProxy();
            }
            // We return null if we do not recognize this proxy! 
            return tp;
        } 
 
        internal static void PushActivationAttributes(Type serverType, Object[] attributes)
        { 
            // There is one such object per thread
            if (_attributeStack == null)
            {
                _attributeStack = new ActivationAttributeStack(); 
            }
            _attributeStack.Push(serverType, attributes); 
        } 

        internal static Object[] PeekActivationAttributes(Type serverType) 
        {
            // We can get a peek w/o a prior Push (eg. activation starting
            // with NewObj)
            if (_attributeStack == null) 
            {
                return null; 
            } 
            return _attributeStack.Peek(serverType);
        } 

        internal static void PopActivationAttributes(Type serverType)
        {
            Contract.Assert(_attributeStack != null, "Pop w/o a prior Set()?"); 
            _attributeStack.Pop(serverType);
        } 
    } // class ActivationServices 

 
    // This is the local activation helper and also the Attribute
    // that gets queried about every activation
    [System.Security.SecurityCritical]  // auto-generated
    internal class LocalActivator: ContextAttribute, IActivator 
    {
        internal LocalActivator() 
            : base(ActivationServices.ActivationServiceURI) 
        {
 
        }

        // ---------------------------------------------------------------
        // ContextAttribute functionality 
        // ---------------------------------------------------------------
 
        // IContextAttribute::IsContextOK 
        // This will check if a type is configured for remote activation ...
        // We return 'false' for IsContextOK if it is. 
        [System.Security.SecurityCritical]
        public override bool IsContextOK(
            Context ctx, IConstructionCallMessage ctorMsg)
        { 

            // If the app is not using config mechanism, we don't want 
            // to intercept activation. 
            if (RemotingConfigHandler.Info == null)
            { 
                return true;
            }

            // check if this type is configured for connect 
            // (instead of remote activate)
            RuntimeType activationType = ctorMsg.ActivationType as RuntimeType; 
            if (activationType == null) 
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
 
            WellKnownClientTypeEntry wkte =
                RemotingConfigHandler.IsWellKnownClientType(activationType);
            String typeURL = (wkte == null ? null : wkte.ObjectUrl);
 
            if (typeURL != null)
            { 
                // this type does have a direct uri, we will try to connect 
                // to it during the activate call. Cache it in the message.
                ctorMsg.Properties[ActivationServices.ConnectKey] = typeURL; 
                return false;
            }
            else
            { 
                ActivatedClientTypeEntry acte =
                    RemotingConfigHandler.IsRemotelyActivatedClientType(activationType); 
 
                String appURL = null;
 
                if (acte == null)
                {
                    // This is the case where the config file had no entry for this type.
                    // We should check the callsite attributes for a URL 
                    Object[] callsiteAttributes = ctorMsg.CallSiteActivationAttributes;
                    if(null != callsiteAttributes) 
                    { 
                        for(int i = 0; i < callsiteAttributes.Length; i++)
                        { 
                            UrlAttribute attr = callsiteAttributes[i] as UrlAttribute;
                            if(null != attr)
                            {
                                appURL = attr.UrlValue; 
                            }
                        } 
                    } 

                    if(appURL == null) 
                    {
                        // We don't really care about intercepting the activation in this case.
                        return true;
                    } 
                }
                else 
                { 
                    appURL = acte.ApplicationUrl;
                } 

                // Generate the URL of the remote activator
                String activatorURL = null;
                if (!appURL.EndsWith("/", StringComparison.Ordinal)) 
                    activatorURL = appURL + "/" + ActivationServices.ActivationServiceURI;
                else 
                    activatorURL = appURL + ActivationServices.ActivationServiceURI; 

                // Mark a flag for remote activation 
                // (caching the url of the activation svc of the remote server)
                ctorMsg.Properties[ActivationServices.RemoteActivateKey] = activatorURL;
                return false;
            } 
        }
 
        // IContextAttribute::GetPropertiesForNewContext 
        [System.Security.SecurityCritical]
        public override void GetPropertiesForNewContext( 
            IConstructionCallMessage ctorMsg)
        {
            BCLDebug.Log("ActivationSvc:GlobalAttrib::GetPropForNewCtx");
            // This is called during RS::Activate .. when we are sure that 
            // activation is at least x-context and this is a real activation
            // instead of a spoofed connect underneath the "new". 
            Contract.Assert(ctorMsg!=null, "ctorMsg null?"); 
            if (ctorMsg.Properties.Contains(ActivationServices.RemoteActivateKey))
            { 
                // Means we did want to intercept activation!
                String remActivatorURL = (String)
                    ctorMsg.Properties[ActivationServices.RemoteActivateKey];
 
                AppDomainLevelActivator activator =
                    new AppDomainLevelActivator(remActivatorURL); 
                // Chain ourselves at the end of the AppDomainLevel activators 
                Contract.Assert(
                        ctorMsg.Activator != null, 
                        "Should have at least x-context activator");
                IActivator curr = ctorMsg.Activator;

                if (curr.Level < ActivatorLevel.AppDomain) 
                {
                    // Common case .. .only x-context activator(s) in chain 
                    activator.NextActivator = curr; 
                    ctorMsg.Activator = activator;
                } 
                else if (curr.NextActivator == null)
                {
                    // Only one activator but not ContextLevel ...
                    // We go at the end of the chain 
                    curr.NextActivator = activator;
                } 
                else 
                {
                    // We will have to walk the chain till the end of the last 
                    // AD activator and plug ourselves in.
                    while (curr.NextActivator.Level >= ActivatorLevel.AppDomain)
                    {
                        curr = curr.NextActivator; 
                    }
                    Contract.Assert( 
                        curr.NextActivator.Level.Equals(ActivatorLevel.Context), 
                        "bad ordering of activators!");
                    activator.NextActivator = curr.NextActivator; 
                    curr.NextActivator = activator;
                }
            }
        } 

        // --------------------------------------------------------------- 
        // IActivator functionality 
        // ----------------------------------------------------------------
        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        {
            // We are a singleton internal infrastructure object.
            [System.Security.SecurityCritical] 
            get { return null; }
            // Don't allow a set either. 
            [System.Security.SecurityCritical] 
            set { throw new InvalidOperationException(); }
        } 

        //IActivator::ActivatorLevel
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]
            get { return ActivatorLevel.AppDomain; } 
        } 

        private static MethodBase GetMethodBase(IConstructionCallMessage msg) 
        {
            MethodBase mb = msg.MethodBase;
            if(null == mb)
            { 
                BCLDebug.Trace("REMOTE", "Method missing w/name ", msg.MethodName);
                    throw new RemotingException( 
                        String.Format( 
                            CultureInfo.CurrentCulture, Environment.GetResourceString(
                                "Remoting_Message_MethodMissing"), 
                            msg.MethodName,
                            msg.TypeName));
            }
 
            return mb;
        } 
 
        //IActivator::Activate
        [System.Security.SecurityCritical] 
        [System.Runtime.InteropServices.ComVisible(true)]
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg)
        { 
            // This is where the activation service hooks in to activation
            // requests. We get called as the activation message is recognized 
            // by the ClientContextTerminatorSink & routed to us. 
            //
            // NOTE: This gets called for both purely within appDomain activation 
            // and 'real' remote activation scenarios as the request goes out of
            // the client context.
            // It also gets called as an incoming remote call is routed to the
            // local activator by the remote activator object. 
            //
            BCLDebug.Log("Activation Services:: new Activate()"); 
            if (ctorMsg == null) 
            {
                throw new ArgumentNullException("ctorMsg"); 
            }
            Contract.EndContractBlock();

            // Check if we have marked this activation to go remote 
            if (ctorMsg.Properties.Contains(ActivationServices.RemoteActivateKey))
            { 
                //DBG Console.WriteLine("Attempting remote activation!"); 

                return DoRemoteActivation(ctorMsg); 
            }
            else
            {
                // We must be in either a pure cross context activation or 
                // a remote incoming activation request (in which case we
                // already checked the permission to create an instance of 
                // this type). 
                if (ctorMsg.Properties.Contains(ActivationServices.PermissionKey))
                { 
                    Type activationType = ctorMsg.ActivationType;

                    // We are on the server end of a real remote activation
                    // Create a local attribute that contributes the context 
                    // properties requested by the remote request
                    Object[] attr = null; 
                    if (activationType.IsContextful) 
                    {
                    IList cp = ctorMsg.ContextProperties; 
                    if (cp != null && cp.Count > 0)
                    {
                        RemotePropertyHolderAttribute rph = new RemotePropertyHolderAttribute(cp);
                        attr = new Object[1]; 
                        attr[0] = rph;
                    } 
                    } 
                    MethodBase mb = GetMethodBase(ctorMsg);
                    RemotingMethodCachedData methodCache = 
                                            InternalRemotingServices.GetReflectionCachedData(mb);
                    Object[] args = Message.CoerceArgs(ctorMsg, methodCache.Parameters);

                    Object server = Activator.CreateInstance( 
                        activationType,
                        args, 
                        attr); 

                    // check to see if we need to do redirection 
                    if (RemotingServices.IsClientProxy(server))
                    {
                        // The wellknown type is remoted so we must wrap the proxy
                        // with a local object. 

                        // The redirection proxy masquerades as an object of the appropriate 
                        // type, and forwards incoming messages to the actual proxy. 
                        RedirectionProxy redirectedProxy =
                            new RedirectionProxy((MarshalByRefObject)server, activationType); 
                        RemotingServices.MarshalInternal(redirectedProxy, null, activationType);

                        server = redirectedProxy;
                    } 

                    return ActivationServices.SetupConstructionReply( 
                        server, ctorMsg, null); 
                }
                else 
                {
                    BCLDebug.Log("Attempting X-Context activation!");
                    // delegate to the Activator in the message
                    return ctorMsg.Activator.Activate(ctorMsg); 
                }
            } 
        } 

 
        // This is called by the local activator during an outgoing activation
        // request.
        internal static IConstructionReturnMessage DoRemoteActivation(
            IConstructionCallMessage ctorMsg) 
        {
            Contract.Assert(ctorMsg != null, "Null ctorMsg"); 
 
            // <
 



            // < 

 
 
            BCLDebug.Log("Attempting Connection to remote activation service");
            IActivator remActivator = null; 
            String remActivatorURL = (String)
                ctorMsg.Properties[ActivationServices.RemoteActivateKey];
            try
            { 
                remActivator = (IActivator)
                    RemotingServices.Connect( 
                        typeof(System.Runtime.Remoting.Activation.IActivator), 
                        remActivatorURL);
 
            }
            catch (Exception e)
            {
                throw new RemotingException( 
                    String.Format(
                        CultureInfo.CurrentCulture, Environment.GetResourceString( 
                            "Remoting_Activation_ConnectFailed"), 
                        e));
            } 
            // Remove the remote activate key as its purpose is served.
            ctorMsg.Properties.Remove(ActivationServices.RemoteActivateKey);

            // Delegate the work to the remote activator 
            return remActivator.Activate(ctorMsg);
        } 
 
    }// class LocalActivator
 
    // This is the object that listens to activation requests
    internal class ActivationListener:MarshalByRefObject, IActivator
    {
        // Override lifetime services to make this object live forever... 
        [System.Security.SecurityCritical]  // auto-generated
        public override Object InitializeLifetimeService() 
        { 
           return null;
        } 

        //IActivator::NextActivator
        public virtual IActivator NextActivator
        { 
            // We are a singleton internal infrastructure object.
            [System.Security.SecurityCritical]  // auto-generated 
            get { return null; } 
            // Don't allow a set either.
            [System.Security.SecurityCritical]  // auto-generated 
            set { throw new InvalidOperationException();}
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get {return ActivatorLevel.AppDomain;}
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            BCLDebug.Log("ActivationListener: received new activation request!");
            if (ctorMsg == null || RemotingServices.IsTransparentProxy(ctorMsg)) 
            {
                throw new ArgumentNullException("ctorMsg");
            }
            Contract.EndContractBlock(); 

            // Add the permission key which distinguishes pure-cross context activation from 
            // a remote request (both of which go through DoCrossContextActivation) 
            ctorMsg.Properties[ActivationServices.PermissionKey] = "allowed";
 
            // Check to make sure that this activation type has been allowed.
            String activationTypeName = ctorMsg.ActivationTypeName;
            if (!RemotingConfigHandler.IsActivationAllowed(activationTypeName))
            { 
                throw new RemotingException(
                    String.Format( 
                        CultureInfo.CurrentCulture, Environment.GetResourceString( 
                            "Remoting_Activation_PermissionDenied"),
                        ctorMsg.ActivationTypeName)); 
            }

            Type activationType = ctorMsg.ActivationType;
            if (activationType == null) 
            {
                throw new RemotingException( 
                    String.Format( 
                        CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"),
                        ctorMsg.ActivationTypeName)); 
            }

            // Delegate to the local activator for further work
            return ActivationServices.GetActivator().Activate(ctorMsg); 
        }
 
 
    }   // class ActivationListener
 

    // This is a lightweight object to help with the activation
    // at the appDomain level ... it delegates its work to
    // ActivationServices.LocalActivator ... which is a heavy 
    // object we can't afford to carry around in the ActivatorChain
    // (since it may get Serialized/Deserialized) 
 [Serializable] 
    // attribute .. the latter shall be turned on during Beta-2!</
    internal class AppDomainLevelActivator : IActivator 
    {
        IActivator m_NextActivator;

        // Do we need this? 
        String m_RemActivatorURL;
 
        internal AppDomainLevelActivator(String remActivatorURL) 
        {
            Contract.Assert(remActivatorURL!=null,"Bad activator URL"); 
            m_RemActivatorURL = remActivatorURL;
        }

        internal AppDomainLevelActivator(SerializationInfo info, StreamingContext context) { 
            if (info==null)
            { 
                throw new ArgumentNullException("info"); 
            }
            Contract.EndContractBlock(); 
            m_NextActivator = (IActivator) info.GetValue("m_NextActivator",typeof(IActivator));
        }

        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return m_NextActivator; }
            [System.Security.SecurityCritical]  // auto-generated 
            set { m_NextActivator = value; }
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return ActivatorLevel.AppDomain; }
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            // This function will get invoked when the ClientContextTerminator sink
            // notices that an activation request message is passed to it ... it 
            // will route the message to the Activator present inside the ctorMsg
            // (which happens to be us in this case!)

            // remove ourselves from the Activator chain 
            ctorMsg.Activator = m_NextActivator;
            return ActivationServices.GetActivator().Activate(ctorMsg); 
        } 
    }
 
    // This is a lightweight object to help with the activation
    // at the context level ...
    [Serializable]
    internal class ContextLevelActivator : IActivator 
    {
        IActivator m_NextActivator; 
        internal ContextLevelActivator() 
        {
            m_NextActivator = null; 
        }

        internal ContextLevelActivator(SerializationInfo info, StreamingContext context)
        { 
            if (info==null)
            { 
                throw new ArgumentNullException("info"); 
            }
            Contract.EndContractBlock(); 
            m_NextActivator = (IActivator) info.GetValue("m_NextActivator",typeof(IActivator));
        }

        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return m_NextActivator; }
            [System.Security.SecurityCritical]  // auto-generated 
            set { m_NextActivator = value; }
        }

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        { 
            [System.Security.SecurityCritical]  // auto-generated 
            get { return ActivatorLevel.Context; }
        } 

        //IActivator::Activate
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg) 
        { 
            // remove ourselves from the Activator chain
            ctorMsg.Activator = ctorMsg.Activator.NextActivator; 

            // Delegate to remoting services to do the hard work.
            // This will create a context, enter it, run through
            // the context sink chain & then delegate to the nex 
            // activator inside the ctorMsg (quite likely to be
            // the default ConstructionLevelActivator) 
            return ActivationServices.DoCrossContextActivation(ctorMsg); 
        }
    } 

    // This is a lightweight object to help with the activation
    // at the appDomain level ... it delegates its work to
    // ActivationServices.LocalActivator ... which is a heavy 
    // object we can't afford to carry around in the ActivatorChain
    // (since it may get Serialized/Deserialized) 
    [Serializable] 
    internal class ConstructionLevelActivator : IActivator
    { 
        internal ConstructionLevelActivator()
        {

        } 

 
        //IActivator::NextActivator 
        public virtual IActivator NextActivator
        { 
            // The construction level activator is a terminating activator
            [System.Security.SecurityCritical]  // auto-generated
            get { return null; }
            // Throw if someone attempts a set 
            [System.Security.SecurityCritical]  // auto-generated
            set { throw new InvalidOperationException(); } 
        } 

        //IActivator::ActivatorLevel 
        public virtual ActivatorLevel Level
        {
            [System.Security.SecurityCritical]  // auto-generated
            get { return ActivatorLevel.Construction; } 
        }
 
        //IActivator::Activate 
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual IConstructionReturnMessage Activate(
            IConstructionCallMessage ctorMsg)
        {
            // This function will get invoked when the ClientContextTerminator sink 
            // notices that an activation request message is passed to it ... it
            // will route the message to the Activator present inside the ctorMsg 
            // (which happens to be us in this case!) 

            // remove ourselves from the Activator chain 
            ctorMsg.Activator = ctorMsg.Activator.NextActivator;
            return ActivationServices.DoServerContextActivation(ctorMsg);
        }
    } 

    // This acts as a pseudo call site attribute and transfers 
    // the context properties carried in from a remote activation request 
    // to the server side activation
    internal class RemotePropertyHolderAttribute : IContextAttribute 
    {
        IList _cp;      // incoming list of context properties
        internal RemotePropertyHolderAttribute(IList cp)
        { 
            _cp = cp;
            Contract.Assert(cp != null && cp.Count > 0,"Bad _cp?"); 
        } 
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)] 
        public virtual bool IsContextOK(Context ctx, IConstructionCallMessage msg)
        {
            // The fact that we got instantiated means some remote activation
            // has contributed non-default context properties to the ctorMsg 
            return false;
        } 
 

        // properties are collected in order from callsite, wom & type 
        // attributes ... so we get a first shot at adding properties
[System.Security.SecurityCritical]  // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
        public virtual void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg) 
        {
            for (int i=0; i<_cp.Count; i++) 
            { 
                // Just cycle through the list and add the properties to
                // the construction message. 
                // We will throw at a later stage if any of these do not
                // implement IContextProperty
                ctorMsg.ContextProperties.Add(_cp[i]);
            } 
        }
    } 
 
    // Note: One instance of this class is setup per thread that comes to
    // managed remoting for activation of MBR types. All access to methods 
    // is by design single-threaded. (Each thread is working on its own object).

    // In the case of Activator.CreateInstance ... that API does the Push &
    // Remoting does a Pop() as soon as it has picked up the attributes from 
    // the threadStatic. The CreateInstance API itself does a Pop() too in
    // a try-finally. (So this does not work very well if the infrastructure 
    // creates an instance of the same MBR type as the outer type being created. 
    // However, to minimize code churn this is the least risky fix we can do.
    // The full fix would be to pass activationAttributes into the VM through 
    // reflection code and have the VM pass them over to remoting which will
    // then hand them over to managed remoting helpers. This will also involve
    // adding attributes as an additional parameter to
    // ProxyAttribute.CreateInstance() public method. 

    internal class ActivationAttributeStack 
    { 
        Object[] activationTypes;
        Object[] activationAttributes; 
        int freeIndex;
        internal ActivationAttributeStack()
        {
            activationTypes = new Object[4]; 
            activationAttributes = new Object[4];
            freeIndex = 0; 
        } 

        internal void Push(Type typ, Object[] attr) 
        {
            Contract.Assert(typ!=null, "typ != null");
            Contract.Assert(attr!=null, "attr != null");
 
            if (freeIndex == activationTypes.Length)
            { 
                // Need to grow our arrays ... this will be exceedingly rare 
                Object[] newTypes = new Object[activationTypes.Length * 2];
                Object[] newAttr = new Object[activationAttributes.Length * 2]; 
                Contract.Assert(newAttr.Length == newTypes.Length,"These should be in [....]!");
                Array.Copy(activationTypes, newTypes, activationTypes.Length);
                Array.Copy(activationAttributes, newAttr, activationAttributes.Length);
                activationTypes = newTypes; 
                activationAttributes = newAttr;
            } 
            activationTypes[freeIndex] = typ; 
            activationAttributes[freeIndex] = attr;
            freeIndex++; 
        }

        internal Object[] Peek(Type typ)
        { 
            Contract.Assert(typ!=null, "typ != null");
            if (freeIndex == 0 || activationTypes[freeIndex-1] != (object)typ) 
            { 
                return null;
            } 
            return (Object[])activationAttributes[freeIndex-1];
        }

        // Note: Read the comments above .. you can have 2 pops for the same 
        // push. We also count on infrastructure code not activating
        // the same type as the caller causing a recursive activation. 
        internal void Pop(Type typ) 
        {
            Contract.Assert(typ!=null, "typ != null"); 
            if (freeIndex != 0 && activationTypes[freeIndex-1] == (object)typ)
            {
                freeIndex--;
                // Clear the popped entry 
                activationTypes[freeIndex] = null;
                activationAttributes[freeIndex] = null; 
            } 
        }
    } 
}//namespace

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
